管道作业前6题

This commit is contained in:
flykhan 2023-08-18 01:09:47 +08:00
parent 15ef646981
commit 0903b37b35
9 changed files with 445 additions and 0 deletions

1
day4/homework/a.txt Normal file
View File

@ -0,0 +1 @@
hihao shijie

47
day4/homework/h1.c Normal file
View File

@ -0,0 +1,47 @@
// 创建一个无名管道,并在父子进程之间传递数据。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
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[32] = "";
int len = read(fd[0], buf, 32);
buf[strlen(buf) - 1] = '\0';
printf("子进程(%d)收到父进程(%d)数据: %s\n", getpid(), getppid(), buf);
close(fd[0]);
_exit(0);
}
else if (pid > 0)
{
// 父进程
close(fd[0]);
printf("父进程正在写入数据\n");
/*
sleep(2)
*/
// sleep(2);
// char buf[32] = "hello pipe";
char buf[32];
fgets(buf, 32, stdin);
write(fd[1], buf, strlen(buf));
close(fd[1]);
}
return 0;
}

55
day4/homework/h2.c Normal file
View File

@ -0,0 +1,55 @@
// 创建两个子进程,一个子进程向管道写入数据,另一个子进程从管道读取数据。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
int fd[2];
int f = pipe(fd);
if (f == -1)
{
perror("pipe");
return 1;
}
int i = 0;
for (; i < 2; i++)
{
pid_t pid = fork();
if (pid == 0)
break; // 子进程跳出循环
}
// 子进程1代码
if (i == 0)
{
close(fd[0]); // 子进程1关闭管道读端
char msg[32] = "";
printf("请在子进程 1 中输入一段内容: ");
scanf("%s", msg);
write(fd[1], msg, strlen(msg) + 1); // 包括'\0' , 写入管道
close(fd[1]); // 关闭管道写端
return 0; // 子进程1退出
}
// 子进程2代码
else if (i == 1)
{
close(fd[1]); // 子进程2关闭管道写端
char buf[32] = "";
int len = read(fd[0], buf, sizeof(buf));
printf("子进程 2 收到子进程 1 数据: %s\n", buf);
close(fd[0]); // 关闭管道读端
return 0; // 子进程2退出
}
// 父进程代码
waitpid(0, NULL, 0); // 等待所有子进程退出
return 0;
}

72
day4/homework/h3.c Normal file
View File

@ -0,0 +1,72 @@
// 创建两个子进程一个子进程向从标准输入读取数据并向管道写入数据另一个子进程从管道读取数据并输出标准设备。当输入的数据是bye时则退出。父进程等待所有子进程退出。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
int fd[2];
int f = pipe(fd);
if (f == -1)
{
perror("pipe");
_exit(1);
}
int i = 0;
for (; i < 2; i++)
{
pid_t pid = fork();
if (pid == 0)
break; // 子进程跳出循环
}
if (i == 0)
{
close(fd[0]); // 子进程1关闭管道读端
printf("请在子进程 1 中输入一段内容:\n");
while (1)
{
char msg[32] = "";
fgets(msg, 32, stdin);
msg[strcspn(msg, "\n")] = '\0'; // 去掉换行符
write(fd[1], msg, strlen(msg) + 1); // 包括'\0' , 写入管道
if (strcmp(msg, "bye") == 0)
break; // 如果输入 "bye"子进程1退出循环
}
close(fd[1]); // 关闭管道写端
_exit(0); // 子进程1退出
}
else if (i == 1)
{
close(fd[1]); // 子进程2关闭管道写端
while (1)
{
char buf[32] = "";
int len = read(fd[0], buf, 32);
if (len <= 0)
break; // 如果读取失败或到达文件末尾子进程2退出循环
if (strcmp(buf, "bye") == 0)
break; // 如果收到 "bye"子进程2退出循环
printf("子进程 2 收到子进程 1 数据: %s\n", buf);
}
close(fd[0]); // 关闭管道读端
_exit(0); // 子进程2退出
}
while (1)
{
int p_id = waitpid(-1, NULL, 0);
if (p_id == -1)
break; // 等待所有子进程退出后,父进程退出循环
}
return 0;
}

80
day4/homework/h4.c Normal file
View File

@ -0,0 +1,80 @@
/*
fork()
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
pid_t pid1, pid2;
int fd1[2], fd2[2];
int f1 = pipe(fd1);
int f2 = pipe(fd2);
if (f1 == -1 || f2 == -1)
{
perror("pipe"); // 创建管道失败
_exit(1); // 创建管道失败,退出
}
pid1 = fork();
if (pid1 == 0)
{
close(fd1[1]); // 子进程1关闭管道写端
char buf[32] = "";
int len = read(fd1[0], buf, sizeof(buf));
printf("子进程 1 收到父进程数据: %s\n", buf);
for (int i = 0; i < strlen(buf); i++)
{
if (buf[i] >= 'a' && buf[i] <= 'z')
buf[i] -= 32;
}
write(fd2[1], buf, strlen(buf) + 1); // 包括'\0' , 写入管道
close(fd2[1]); // 关闭管道写端
_exit(0); // 子进程1退出
}
pid2 = fork();
if (pid2 == 0)
{
close(fd2[1]); // 子进程2关闭管道写端
char buf[32] = "";
int len = read(fd2[0], buf, sizeof(buf));
printf("子进程 2 收到子进程 1 数据: %s\n", buf);
close(fd2[0]); // 关闭管道读端
_exit(0); // 子进程2退出
}
close(fd1[0]); // 父进程关闭管道读端
char msg[32] = "";
printf("请在父进程中输入一段内容: ");
scanf("%s", msg);
write(fd1[1], msg, strlen(msg) + 1); // 包括'\0' , 写入管道
close(fd1[1]); // 关闭管道写端
/*
: 0退NULL表示不关心子进程退出状态0
: 退pid退-1
: 退退
: 退退
1 退; 2 退
-1 退
WNOHANG
WUNTRACED
WCONTINUED
WIFEXITED(status) 退0
WEXITSTATUS(status) WIFEXITED(status)0退
WIFSIGNALED(status) 退0
*/
waitpid(0, NULL, 0); // 等待所有子进程退出
return 0;
}

60
day4/homework/h5.c Normal file
View File

@ -0,0 +1,60 @@
// 创建一个父进程和一个子进程,父进程从文件读取数据,并通过管道发送给子进程,子进程将数据输出到标准输出。
// 例如父进程从文件读取到的数据为hello world子进程将输出hello world
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
int main()
{
pid_t pid;
int fd[2];
int f = pipe(fd);
if (f == -1)
{
perror("pipe"); // 创建管道失败
_exit(1); // 创建管道失败,退出
}
pid = fork();
if (pid == 0)
{
close(fd[1]); // 子进程关闭管道写端
char buf[32] = "";
int len = read(fd[0], buf, sizeof(buf));
// buf[len] = '\0'; // 不加'\0',父进程读取到的数据会有乱码
printf("子进程收到父进程数据: %s", buf);
close(fd[0]); // 关闭管道读端
_exit(0); // 子进程退出
}
close(fd[0]); // 父进程关闭管道读端
int fd_file = open("a.txt", O_RDONLY); // 打开文件
if (fd_file == -1)
{
perror("open");
_exit(1);
}
char buf[32] = "";
int len = read(fd_file, buf, sizeof(buf));
if (len == -1)
{
perror("read");
_exit(1);
}
// 不加'\0',子进程读取到的数据会有乱码
write(fd[1], buf, strlen(buf) /* + 1 */); // 包括'\0' , 写入管道
close(fd[1]); // 关闭管道写端
close(fd_file);
waitpid(0, NULL, 0); // 等待子进程退出
return 0;
}

57
day4/homework/h6.c Normal file
View File

@ -0,0 +1,57 @@
// 创建两个子进程,一个子进程向有名管道写入数据,另一个子进程从有名管道读取数据。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
int main()
{
if (mkfifo("fifo", 0644) == -1) // 创建有名管道
{
// 如果有名管道已经存在,不报错
// 如果是其他错误,报错
if (errno != EEXIST)
{
perror("mkfifo");
_exit(1);
}
}
int fd = open("fifo", O_RDWR); // 打开有名管道
if (fd == -1)
{
perror("open");
_exit(1);
}
int i = 0;
for (; i < 2; i++)
{
pid_t pid = fork();
if (pid == 0)
break; // 子进程跳出循环
}
if (i == 0)
{
char msg[32] = "";
printf("请在子进程 1 中输入一段内容: ");
scanf("%s", msg);
write(fd, msg, strlen(msg) + 1); // 包括'\0' , 写入管道
}
else if (i == 1)
{
char buf[32] = "";
int len = read(fd, buf, sizeof(buf));
printf("子进程 2 收到子进程 1 数据: %s\n", buf);
}
close(fd); // 关闭管道
waitpid(0, NULL, 0);
return 0;
}

6
day4/homework/h7.c Normal file
View File

@ -0,0 +1,6 @@
// 创建父子进程, 在父进程中输入命令,在子进程中执行,并将执行结果发送给父进程,父进程进行打印输出。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

67
day4/homework/test.c Normal file
View File

@ -0,0 +1,67 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
int fd[2];
int f = pipe(fd);
if (f == -1)
{
perror("pipe");
_exit(1);
}
int i = 0;
for (; i < 2; i++)
{
pid_t pid = fork();
if (pid == 0)
break;
}
if (i == 0)
{
close(fd[0]);
printf("请在子进程 1 中输入一段内容:\n");
while (1)
{
char msg[32] = "";
fgets(msg, 32, stdin);
msg[strcspn(msg, "\n")] = '\0'; // 去掉换行符
write(fd[1], msg, strlen(msg) + 1); // 包括'\0' , 写入管道
if (strcmp(msg, "bye") == 0)
break;
}
close(fd[1]);
_exit(0);
}
else if (i == 1)
{
close(fd[1]);
while (1)
{
char buf[32] = "";
int len = read(fd[0], buf, 32);
if (len <= 0)
break;
if (strcmp(buf, "bye") == 0)
break;
printf("子进程 2 收到子进程 1 数据: %s\n", buf);
}
close(fd[0]);
_exit(0);
}
while (1)
{
int p_id = waitpid(-1, NULL, 0);
if (p_id == -1)
break;
}
return 0;
}