From ef704ce9f197cc7d9aa2ad4eacc29fee62cd9565 Mon Sep 17 00:00:00 2001 From: flykhan Date: Tue, 15 Aug 2023 19:05:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=20,=20?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- day2/d1.c | 21 +++++++++++++++++ day2/d2.c | 52 ++++++++++++++++++++++++++++++++++++++++++ day2/d3.c | 27 ++++++++++++++++++++++ day2/d4.c | 17 ++++++++++++++ day2/d5.c | 48 +++++++++++++++++++++++++++++++++++++++ day2/d6.c | 13 +++++++++++ day2/d7.c | 18 +++++++++++++++ day2/d8.c | 43 +++++++++++++++++++++++++++++++++++ day2/d9.c | 42 ++++++++++++++++++++++++++++++++++ day2/test_fork.c | 32 ++++++++++++++++++++++++++ day2/test_fork2.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ day2/test_fork3.c | 38 +++++++++++++++++++++++++++++++ day2/test_pid.c | 21 +++++++++++++++++ 13 files changed, 429 insertions(+) create mode 100644 day2/d1.c create mode 100644 day2/d2.c create mode 100644 day2/d3.c create mode 100644 day2/d4.c create mode 100644 day2/d5.c create mode 100644 day2/d6.c create mode 100644 day2/d7.c create mode 100644 day2/d8.c create mode 100644 day2/d9.c create mode 100644 day2/test_fork.c create mode 100644 day2/test_fork2.c create mode 100644 day2/test_fork3.c create mode 100644 day2/test_pid.c diff --git a/day2/d1.c b/day2/d1.c new file mode 100644 index 0000000..01fc77a --- /dev/null +++ b/day2/d1.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +int main(int argc, char *argv[]) +{ + // 修改标准的输入设备的标识为非阻塞 + int flags = fcntl(STDIN_FILENO, F_GETFL); + flags |= O_NONBLOCK; // 添加非阻塞标识,可以注释这一行来测试不同的效果 + fcntl(STDIN_FILENO, F_SETFL, flags); + + char buf[32] = ""; + printf("准备读取数据......\n"); + // read 默认是阻塞的,如果没有数据,会一直等待 + // 接收到一个回车,read就会返回 + ssize_t len = read(STDIN_FILENO, buf, sizeof(buf)); + printf("读取的内容为:%s\n", buf); + + return 0; +} \ No newline at end of file diff --git a/day2/d2.c b/day2/d2.c new file mode 100644 index 0000000..373074e --- /dev/null +++ b/day2/d2.c @@ -0,0 +1,52 @@ +// 使用系统调用实现cp命令 +// 1. 打开源文件 +// 2. 创建目标文件 +// 3. 循环读取源文件,写入目标文件 +// 4. 关闭文件 +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int srcfd, dstfd; + char buf[1024]; + int len; + + if (argc < 3) + { + printf("./a.out srcfile dstfile\n"); + exit(1); + } + + // 打开源文件 + srcfd = open(argv[1], O_RDONLY); + if (srcfd < 0) + { + perror("open"); + exit(1); + } + + // 创建目标文件 + dstfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664); + if (dstfd < 0) + { + perror("open"); + exit(1); + } + + // 循环读取源文件,写入目标文件 + while ((len = read(srcfd, buf, sizeof(buf))) > 0) + { + write(dstfd, buf, len); + } + + // 关闭文件 + close(srcfd); + close(dstfd); + + return 0; +} + +// ./a.out srcfile dstfile \ No newline at end of file diff --git a/day2/d3.c b/day2/d3.c new file mode 100644 index 0000000..e181f4f --- /dev/null +++ b/day2/d3.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +// 使用 stat 函数获取文件的信息,并判断文件类型 +int main(int argc, char const *argv[]) +{ + const char *path = argv[1]; // 获取命令行参数中的文件路径 + + struct stat fileStat; + if (stat(path, &fileStat) == 0) + { + // 获取文件信息成功 + if (fileStat.st_mode & __S_IFDIR) + { + printf("%s 是一个目录\n", path); // 判断文件是否为目录,并输出相应信息 + } + else if (fileStat.st_mode & __S_IFREG) + { + printf("%s 是一个普通文件\n", path); // 判断文件是否为普通文件,并输出相应信息 + } + } + + return 0; // 返回成功码 +} diff --git a/day2/d4.c b/day2/d4.c new file mode 100644 index 0000000..df9ab6b --- /dev/null +++ b/day2/d4.c @@ -0,0 +1,17 @@ +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + printf("正在运行程序,进程号: %d\n", getpid()); + while (1) + ; + + return 0; +} + +/* + ps -ef | grep a.out 查询进程号 + kill -9 进程号 杀死进程 +*/ \ No newline at end of file diff --git a/day2/d5.c b/day2/d5.c new file mode 100644 index 0000000..7c7f4b6 --- /dev/null +++ b/day2/d5.c @@ -0,0 +1,48 @@ +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int n = 100; + int total = 0; + + // 父进程完成 给定的整数以内的 3 的倍数的和 + // 子进程完成 给定的整数以内的 5 的倍数的和 + + pid_t pid = fork(); + if (pid < 0) + { + perror("fork error"); + return -1; // fork 出错, 退出 + } + if (pid == 0) + { + // 子进程 + for (int i = 1; i <= n; i++) + { + if (i % 5 == 0) + { + total += i; + } + } + printf("子进程(%d) : 1-%d 以内的 5 的倍数的和为: %d\n", getpid(), n, total); + } + else + { + // 父进程 + for (int i = 1; i <= n; i++) + { + if (i % 3 == 0) + { + total += i; + } + } + printf("父进程(%d): 1-%d 以内的 3 的倍数的和为: %d\n", getpid(), n, total); + } + printf("进程(%d) 退出\n", getpid()); + // while (1) + // ; + + return 0; +} diff --git a/day2/d6.c b/day2/d6.c new file mode 100644 index 0000000..6ca847a --- /dev/null +++ b/day2/d6.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + printf("%d fork before\n", getpid()); // 向缓冲区写入数据 + int pid = fork(); + // int pid2 = fork(); + // int pid3 = fork(); + // printf("%d fork after\n", getpid()); // 向缓冲区写入数据 + return 0; +} \ No newline at end of file diff --git a/day2/d7.c b/day2/d7.c new file mode 100644 index 0000000..cd1eead --- /dev/null +++ b/day2/d7.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + time_t at = time(NULL); + char buf[32] = ""; + sprintf(buf, "%d 运行中", getpid()); + write(1, buf, sizeof(buf)); + sleep(2); + time_t bt = time(NULL); + printf("\n%d 结束\n", getpid()); + printf("运行时间:%ld 秒\n", bt - at); + + return 0; +} diff --git a/day2/d8.c b/day2/d8.c new file mode 100644 index 0000000..d93dcb5 --- /dev/null +++ b/day2/d8.c @@ -0,0 +1,43 @@ +#include // perror +#include // pid_t +#include // fork +#include // wait + +int main(int argc, char const *argv[]) +{ + int pid = fork(); + + if (pid < 0) + { + perror("fork"); + return -1; + } + if (pid == 0) + { + // write(1, "123", 4); + int n = 10 / 0; + sleep(3); + printf("%d 子进程结束", getpid()); + return 10; + } + else + { + // status 用来保存子进程的退出状态 + int status; + int pid = wait(&status); // 等待子进程结束 + printf("\n%d 父进程中, 等到了子进程 %d 结束, status = %d \n", getpid(), pid, status >> 8); + + // WIFEXITED(status) 为真表示子进程正常退出 + if (WIFEXITED(status) & 0xff00 >> 8) // 子进程是否正常退出 + { + // WEXITSTATUS(status) 获取子进程的退出码 + printf("%d", WEXITSTATUS(status)); + } + else + { + printf("子进程异常退出, status = %d", status >> 8); + } + } + + return 0; +} diff --git a/day2/d9.c b/day2/d9.c new file mode 100644 index 0000000..26c5af9 --- /dev/null +++ b/day2/d9.c @@ -0,0 +1,42 @@ +#include // perror +#include // pid_t +#include // fork +#include // wait + +int main(int argc, char const *argv[]) +{ + int pid = fork(); + + if (pid < 0) + { + perror("fork"); + return -1; + } + if (pid == 0) + { + printf("%d 子进程准备睡眠 3 秒\n", getpid()); + sleep(3); + printf("%d 子进程结束", getpid()); + return 10; + } + else + { + // status 用来保存子进程的退出状态 + int status; + int pid2 = waitpid(pid, &status, WUNTRACED); // 等待子进程结束 + printf("\n%d 父进程中, 等到了子进程 %d 结束, status = %d \n", getpid(), pid, status >> 8); + + // WIFEXITED(status) 为真表示子进程正常退出 + if (WIFEXITED(status) & 0xff00 >> 8) // 子进程是否正常退出 + { + // WEXITSTATUS(status) 获取子进程的退出码 + printf("%d", WEXITSTATUS(status)); + } + else + { + printf("子进程异常退出, status = %d", status >> 8); + } + } + + return 0; +} diff --git a/day2/test_fork.c b/day2/test_fork.c new file mode 100644 index 0000000..26694b9 --- /dev/null +++ b/day2/test_fork.c @@ -0,0 +1,32 @@ +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + pid_t pid; + + pid = fork(); // 创建一个子进程 + if (pid < 0) + perror("fork"); // 如果 fork 失败,打印错误信息 + if (pid == 0) + { + // 子进程代码 + while (1) + { + printf("这是子进程\n"); + sleep(1); // 休眠 1 秒 + } + } + else + { + // 父进程代码 + while (1) + { + printf("这是父进程\n"); + sleep(1); + } + } + + return 0; +} diff --git a/day2/test_fork2.c b/day2/test_fork2.c new file mode 100644 index 0000000..1abb0ca --- /dev/null +++ b/day2/test_fork2.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +static int vax = 18; // 静态全局变量 +int var = 10; // 全局变量 +int main(int argc, char const *argv[]) +{ + pid_t pid; + int num = 9; // 局部变量 + pid = fork(); // 创建子进程 + if (pid < 0) + { + perror("fork"); + } + if (pid == 0) // 子进程 + { + vax--; // 子进程中修改静态全局变量 vax + var++; // 子进程中修改全局变量 var + num++; // 子进程中修改局部变量 num + printf("在子进程的 vax=%d, var=%d, num=%d\n", vax, var, num); + } + else // 父进程 + { + sleep(1); // 父进程等待一秒钟 + printf("在父进程的 vax=%d, var=%d, num=%d\n", vax, var, num); + } + + printf("命令代码区\n"); // 在父进程和子进程中都会执行的代码 + + return 0; +} + +/* +这段代码创建了一个子进程,并在父进程和子进程中分别修改和打印变量 var 和 num 的值。下面是代码的执行过程: + +主进程开始执行,变量 var 被初始化为 10,变量 num 被初始化为 9。 +调用 fork() 创建子进程。 +在父进程中,fork() 返回子进程的进程ID,所以 pid 不为0,进入父进程的分支。 +父进程调用 sleep(1) 休眠一秒钟,让子进程先执行。 +在子进程中,fork() 返回0,进入子进程的分支。 +子进程中,var++ 将全局变量 var 的值加1,num++ 将局部变量 num 的值加1。 +子进程打印输出 "在子进程的 var=11, num=10"。 +父进程等待一秒钟后恢复执行,继续执行下面的代码。 +父进程打印输出 "在父进程的 var=10, num=9"。 +打印输出 "命令代码区"。 +程序结束。 +*/ + +/* +由于 fork() 创建了一个子进程,子进程会复制父进程的内存空间,包括变量的值。因此,父进程和子进程拥有各自独立的变量副本,它们的修改互不影响。 + +在子进程中,变量 var 的值被增加到 11,而变量 num 的值被增加到 10。在父进程中,变量 var 保持为初始值 10,变量 num 保持为初始值 9。这说明父进程和子进程中的变量是独立的。 + +最后的打印输出语句 "命令代码区" 在父进程和子进程中都会执行,因为它们是在 fork() 调用之前执行的代码。 +*/ \ No newline at end of file diff --git a/day2/test_fork3.c b/day2/test_fork3.c new file mode 100644 index 0000000..f77f656 --- /dev/null +++ b/day2/test_fork3.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + pid_t pid; + int length = 0; + char buf[] = "a write to stdout\n"; + + // 向标准输出写入数据 1 表示标准输出 + length = write(1, buf, strlen(buf)); + if (length != strlen(buf)) + { + printf("写入错误\n"); + } + + printf("fork之前\n"); + pid = fork(); // 创建子进程 + if (pid < 0) + { + perror("fork"); // 输出错误信息 + } + else if (pid == 0) // 子进程 + { + printf("在子进程中\n"); + } + else // 父进程 + { + sleep(1); // 等待1秒钟 + printf("在父进程中\n"); + } + printf("fork之后\n"); + + return 0; +} diff --git a/day2/test_pid.c b/day2/test_pid.c new file mode 100644 index 0000000..c0768b0 --- /dev/null +++ b/day2/test_pid.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int main() +{ + // 进程号,父进程号,组进程号 + pid_t pid, ppid, pgid; + + pid = getpid(); // 获取当前进程的进程号 + ppid = getppid(); // 获取当前进程的父进程号 + // pgid = __getpgid(0); // 获取当前进程所属的组进程号 + pgid = getpgid(ppid); + + printf("pid = %d\nppid = %d\npgid = %d\n", pid, ppid, pgid); + + while (1) + ; + + return 0; +}