diff --git a/day4/bbs_bob.c b/day4/bbs_bob.c new file mode 100644 index 0000000..220ed97 --- /dev/null +++ b/day4/bbs_bob.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// 单机聊天工具 (bob方) +int main(int argc, char const *argv[]) +{ +// 使用方法 gcc xx.c -D CREATE_FIFO 会在运行时执行预处理区段 +#ifdef CREATE_FIFO + mkfifo("fifo_bob_to_lucy", 0644); + mkfifo("fifo_lucy_to_bob", 0644); +#endif + + if (mkfifo("fifo_bob_to_lucy", 0644) != -1) + { + if (errno != EEXIST) + { + perror("fifo_bob_to_lucy"); + return 1; + } + } + if (mkfifo("fifo_lucy_to_bob", 0644) != -1) + { + if (errno != EEXIST) + { + perror("fifo_lucy_to_bob"); + return 1; + } + } + + int i = 0; + for (; i < 2; i++) + { + int pid = fork(); + if (pid == 0) + break; + } + if (i == 0) + { + // 第一个子进程 + // 从键盘输入数据并发送给对方 (bob -> lucy) + int fd = open("fifo_bob_to_lucy", O_WRONLY); // 只写消息 + while (1) + { + char buf[128] = {}; + int len = read(STDIN_FILENO, buf, 128); + buf[len - 1] = '\0'; + write(fd, buf, len); + if (strcmp(buf, "bye") == 0) + { + break; + } + } + close(fd); + _exit(0); + } + else if (i == 1) + { + // 第二个进程,读数据 (lucy -> bob) + int fd = open("fifo_lucy_to_bob", O_RDONLY); + while (1) + { + char buf[128] = ""; + int len = read(fd, buf, 128); + if (len <= 0) + break; + printf("接收 Lucy: %s\n", buf); + } + close(fd); + _exit(0); + } + else + { + // 主进程 + while (1) + { + // int status; + int pid_ = waitpid(0, NULL, WNOHANG); + if (pid_ == -1) + { + // 所有子进程都已经退出 + break; + } + } + } + return 0; +} diff --git a/day4/bbs_lucy.c b/day4/bbs_lucy.c new file mode 100644 index 0000000..cbe740d --- /dev/null +++ b/day4/bbs_lucy.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// 单机聊天工具 (lucy方) +int main(int argc, char const *argv[]) +{ +// 使用方法 gcc xx.c -D CREATE_FIFO 会在运行时执行预处理区段 +#ifdef CREATE_FIFO + mkfifo("fifo_bob_to_lucy", 0644); + mkfifo("fifo_lucy_to_bob", 0644); +#endif + + if (mkfifo("fifo_bob_to_lucy", 0644) != -1) + { + if (errno != EEXIST) + { + perror("fifo_bob_to_lucy"); + return 1; + } + } + if (mkfifo("fifo_lucy_to_bob", 0644) != -1) + { + if (errno != EEXIST) + { + perror("fifo_lucy_to_bob"); + return 1; + } + } + + int i = 0; + for (; i < 2; i++) + { + int pid = fork(); + if (pid == 0) + break; + } + if (i == 0) + { + // 第一个子进程 + // 从键盘输入数据并发送给对方 (lucy -> bob) + int fd = open("fifo_lucy_to_bob", O_WRONLY); // 只写消息 + while (1) + { + char buf[128] = {}; + int len = read(STDIN_FILENO, buf, 128); + buf[len - 1] = '\0'; + write(fd, buf, len); + if (strcmp(buf, "bye") == 0) + { + break; + } + } + close(fd); + _exit(0); + } + else if (i == 1) + { + // 第二个进程,读数据 (bob -> lucy) + int fd = open("fifo_bob_to_lucy", O_RDONLY); + while (1) + { + char buf[128] = ""; + int len = read(fd, buf, 128); + if (len <= 0) + break; + printf("接收 Bob: %s\n", buf); + } + close(fd); + _exit(0); + } + else + { + // 主进程 + while (1) + { + // int status; + int pid_ = waitpid(0, NULL, WNOHANG); + if (pid_ == -1) + { + // 所有子进程都已经退出 + break; + } + } + } + return 0; +} diff --git a/day4/demo1.c b/day4/demo1.c new file mode 100644 index 0000000..c32c384 --- /dev/null +++ b/day4/demo1.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int fd[2]; + if (pipe(fd) == -1) + { + perror("pipe"); + return 1; + } + + pid_t pid = fork(); + if (pid == 0) + { + close(fd[1]); + dup2(fd[0], 0); // 0 -> fd[0] ,标准输入设备改为管道 + execlp("grep", "grep", "fish", NULL); + close(fd[0]); + _exit(0); + } + + else if (pid > 0) // 父进程 + { + close(fd[0]); // 关闭读 + // 将命令执行结果写入管道中 + dup2(fd[1], 1); // 1 -> fd[1] ,标准输出设备改为管道 + execlp("ps", "ps", "-A", NULL); + close(fd[1]); + // wait(pid); + } + + return 0; +} diff --git a/day4/demo2.c b/day4/demo2.c new file mode 100644 index 0000000..67d9f8c --- /dev/null +++ b/day4/demo2.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int fd[2]; + if (pipe(fd) == -1) + { + perror("pipe"); + return 1; + } + + pid_t pid = fork(); + if (pid == 0) + { + close(fd[0]); // 关闭读 + // 重定向标准输出到管道 + dup2(fd[1], 1); + execlp("expr", "expr", "4", "+", "5", NULL); + close(fd[1]); + _exit(0); + } + + else if (pid > 0) // 父进程 + { + close(fd[1]); // 关闭写 + char buf[10] = {}; + int len = read(fd[0], buf, 10); + buf[len - 1] = '\0'; + printf("读取子进程发送的数据: %s\n", buf); + close(fd[0]); + } + + return 0; +} diff --git a/day4/fifo_read.c b/day4/fifo_read.c new file mode 100644 index 0000000..a998839 --- /dev/null +++ b/day4/fifo_read.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + // 创建 fifo 的有名(文件名)管道 if (mkfifo("myfifo", 0755) != 0) + if (mkfifo("myfifo", 0755) != 0) + { + if (errno != EEXIST) + { + perror("mkfifo"); + return 1; + } + } + + printf("准备以只读方式打开 myfifo\n"); + int fd = open("myfifo", O_RDONLY); + printf("open myfifo fd = %d\n", fd); + int n = 1; + while (1) + { + char buf[32] = ""; + int len = read(fd, buf, 32); // 阻塞(写进程运行期间),非阻塞(没有写进程运行) + buf[len - 1] = '\0'; + printf("第%d次读取的数据(%d Bytes): %s\n", n++, len, buf); + sleep(1); + } + close(fd); + return 0; +} \ No newline at end of file diff --git a/day4/fifo_read_2.c b/day4/fifo_read_2.c new file mode 100644 index 0000000..b80f726 --- /dev/null +++ b/day4/fifo_read_2.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + // 创建 fifo 的有名(文件名)管道 if (mkfifo("myfifo", 0755) != 0) + if (mkfifo("myfifo", 0755) != 0) + { + if (errno != EEXIST) + { + perror("mkfifo"); + return 1; + } + } + + printf("准备以只读方式打开 myfifo\n"); + int fd = open("myfifo", O_RDONLY | O_NONBLOCK); // 非阻塞 + printf("open myfifo fd = %d\n", fd); + int n = 1; + while (1) + { + char buf[32] = ""; + int len = read(fd, buf, 32); // 阻塞(写进程运行期间),非阻塞(没有写进程运行) + buf[len - 1] = '\0'; + printf("第%d次读取的数据(%d Bytes): %s\n", n++, len, buf); + sleep(1); + } + close(fd); + return 0; +} \ No newline at end of file diff --git a/day4/fifo_write.c b/day4/fifo_write.c new file mode 100644 index 0000000..b0db717 --- /dev/null +++ b/day4/fifo_write.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + // 创建 fifo 的有名(文件名)管道 + if (mkfifo("myfifo", 0755) != 0) + { + if (errno != EEXIST) + { + + perror("mkfifo"); + return 1; + } + } + + printf("准备以只写方式打开 myfifo\n"); + int fd = open("myfifo", O_WRONLY); + printf("open myfifo fd = %d\n", fd); + + sleep(3); // 阻塞 5 秒 + + close(fd); + return 0; +} \ No newline at end of file diff --git a/day4/fifo_write_2.c b/day4/fifo_write_2.c new file mode 100644 index 0000000..403bec9 --- /dev/null +++ b/day4/fifo_write_2.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + // 创建 fifo 的有名(文件名)管道 + if (mkfifo("myfifo", 0755) != 0) + { + // 管道文件已经存在,代码将继续执行后面的部分,其他错误报错 + // 如果errno等于EEXIST,则表示管道文件已经存在,代码将继续执行后面的部分 + if (errno != EEXIST) + { + + perror("mkfifo"); + return 1; + } + } + + printf("准备以只写方式打开 myfifo\n"); + int fd = open("myfifo", O_WRONLY | O_NONBLOCK); + if (fd == -1) + { + perror("open"); + return 1; + } + + printf("open myfifo fd = %d\n", fd); + + sleep(3); // 阻塞 5 秒 + + close(fd); + return 0; +} \ No newline at end of file diff --git a/day4/file1.c b/day4/file1.c new file mode 100644 index 0000000..d0436d9 --- /dev/null +++ b/day4/file1.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +int main() +{ + close(1); // 关闭标准输出描述符 + int fd = open("a.txt", O_WRONLY | O_CREAT | O_APPEND, 0644); + printf("hello fd\n"); // fd 描述符会变为 1 ,printf 回答引导 fd 对应文件中 + + return 0; +} \ No newline at end of file diff --git a/day4/file2.c b/day4/file2.c new file mode 100644 index 0000000..d37a42e --- /dev/null +++ b/day4/file2.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +int main() +{ + int fd = open("a.txt", O_WRONLY | O_CREAT | O_APPEND, 0644); + printf("新打开的hello fd\n"); // fd 描述符会变为 1 ,printf 回答引导 fd 对应文件中 + close(1); // 关闭标准输出(文件描述符为1 ) + int newfd = dup(fd); // 1->a.txt,会分配当前最小可用的文件描述符(这个时候标准输出1的描述符空闲),即拿到文件描述符1 + // 下面的打印(写入)会重定向到 a.txt 文件中 + printf("newfd = %d\n", newfd); + printf("hahah\n"); + close(fd); + printf("yes\n"); + + return 0; +} \ No newline at end of file diff --git a/day4/file3_dup2.c b/day4/file3_dup2.c new file mode 100644 index 0000000..ba41d29 --- /dev/null +++ b/day4/file3_dup2.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +int main() +{ + int fd = open("a.txt", O_WRONLY | O_CREAT | O_APPEND, 0644); + printf("新打开的hello fd\n"); // fd 描述符会变为 1 ,printf 回答引导 fd 对应文件中 + // dup2 会自动关闭 newfd,即关闭 1 标准输出 + int newfd = dup2(fd, 1); // 1->a.txt, 会将新的 fd 描述符值为 1 + close(fd); + // 下面的打印(写入)会重定向到 a.txt 文件中 + printf("newfd = %d\n", newfd); + printf("no\n"); + printf("good\n"); + + return 0; +} \ No newline at end of file diff --git a/day4/file4_0.c b/day4/file4_0.c new file mode 100644 index 0000000..bf4179e --- /dev/null +++ b/day4/file4_0.c @@ -0,0 +1,21 @@ +// 配合file4使用 +#include +#include +#include +#include +#include + +int main() +{ + // 设置 1 的 close_on_exec 打开状态(默认为关闭) + int flags; + flags = fcntl(1, F_GETFD); + flags |= FD_CLOEXEC; + // flags &= ~FD_CLOEXEC; // 关闭 FD_CLOEXEC 标志位 + fcntl(1, F_SETFD, flags); + + execl("./file4_1", "file4_1", NULL); // 当 file4_1 存在时,会切换到file4_1运行,不会继续执行本程序后续行内容 + + printf("file4_0"); // 当file4_1不存在时才会执行到这里 + return 0; +} \ No newline at end of file diff --git a/day4/file4_1.c b/day4/file4_1.c new file mode 100644 index 0000000..4df5d1c --- /dev/null +++ b/day4/file4_1.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include +#include + +int main() +{ + printf("hi, file4_1"); + return 0; +} \ No newline at end of file diff --git a/day4/pipe1.c b/day4/pipe1.c new file mode 100644 index 0000000..d46bd7d --- /dev/null +++ b/day4/pipe1.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +int main() +{ + int fd[2]; + int f = pipe(fd); + if (f == -1) + { + perror("pipe"); + return 1; + } + + int pid = fork(); + if (pid == 0) + { + // 子进程: 读 + // 关闭写通道 + close(fd[1]); + + char buf[64] = {}; + int len = read(fd[0], buf, 64); // 可能会阻塞,数据为空时会阻塞 + + printf("%d 子进程读取到: %s\n", getpid(), buf); + // 关闭使用完之后,记得关闭 + close(fd[0]); // 关闭读管道 + _exit(0); + } + else if (pid > 0) + { + // 父进程,写 + // 关闭读通道 + close(fd[0]); + printf("父进程(%d)等待3秒向子进程(%d)写数据\n", getpid(), pid); + sleep(3); + char buf[64] = "hello,flykhan"; + write(fd[1], buf, strlen(buf)); + // 关闭写通道 + close(fd[1]); + } + + return 0; +} \ No newline at end of file diff --git a/day4/pipe3.c b/day4/pipe3.c new file mode 100644 index 0000000..1df2031 --- /dev/null +++ b/day4/pipe3.c @@ -0,0 +1,7 @@ +#include +#include +#include + +int main() +{ +} \ No newline at end of file diff --git a/day4/pipe4.c b/day4/pipe4.c new file mode 100644 index 0000000..28ec58f --- /dev/null +++ b/day4/pipe4.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +int main() +{ + int fd[2]; + int f = pipe(fd); + if (f == -1) + { + perror("pipe"); + return 1; + } + + int pid = fork(); + if (pid == 0) + { + // 子进程: 读 + // 关闭写通道 + close(fd[1]); + for (int i = 0; i < 3; i++) + { + char buf[1024] = {}; + int len = read(fd[0], buf, 1024); // 可能会阻塞,数据为空时会阻塞 + buf[len - 1] = '\0'; + + printf("%d 子进程读取到: %s ,数据大小为 %d\n", getpid(), buf, len); + } + // 关闭使用完之后,记得关闭 + close(fd[0]); // 关闭读管道 + _exit(0); + } + else if (pid > 0) + { + // 父进程,写 + // 关闭读通道 + close(fd[0]); + + // 从键盘读取数据写入到管道中 + while (1) + { + char buf[32] = {""}; + int len = read(0, buf, 32); + write(fd[1], buf, len); + } + + // 关闭写通道 + close(fd[1]); + } + + return 0; +} \ No newline at end of file diff --git a/day4/pipe5.c b/day4/pipe5.c new file mode 100644 index 0000000..4b85b8e --- /dev/null +++ b/day4/pipe5.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +int main() +{ + int fd[2]; + int f = pipe(fd); + if (f == -1) + { + perror("pipe"); + return 1; + } + + int pid = fork(); + if (pid > 0) + { + // 父进程: 读 + // 关闭写通道 + close(fd[1]); + for (int i = 0; i < 3; i++) + { + char buf[1024] = {}; + int len = read(fd[0], buf, 1024); // 可能会阻塞,数据为空时会阻塞 + buf[len - 1] = '\0'; + + printf("%d 父进程读取到: %s ,数据大小为 %d\n", getpid(), buf, len); + } + // 关闭使用完之后,记得关闭 + close(fd[0]); // 关闭读管道 + _exit(0); + } + else if (pid == 0) + { + // 子进程,写 + // 关闭读通道 + close(fd[0]); + + // 从键盘读取数据写入到管道中 + while (1) + { + char buf[32] = {""}; + // int len = read(0, buf, 32); + scanf("%s", buf); + // buf[strlen(buf) - 1] = '\0'; + write(fd[1], buf, strlen(buf) + 1); + } + + // 关闭写通道 + close(fd[1]); + } + + return 0; +} \ No newline at end of file