C语言程序 演示fork()和pipe()
在下面的教程中,我们将了解C语言中fork()和pipe()的实现。
那么,让我们开始吧。
fork()
- fork()函数用于启动一个新的进程。这个子进程是父进程的精确复制品。在类Unix操作系统中,它是创建新进程的主要技术。
- 一个被称为 “子进程 “的新进程通过fork系统函数被创建,并与调用fork()的进程(父进程)同时运行。一旦一个新的子进程被启动,两个进程都将执行fork()系统调用后的下一条指令。父进程所利用的CPU寄存器、程序计数器和打开的文件同样被子进程所使用。
- 它返回一个整数值,不需要参数。fork返回的各种值列在下面()。
pipe()
- 一个管道可以被用来使一个进程向其写入,另一个进程从其读取。这就是所谓的单向通信。它首先打开一个管道,即主内存的一部分,作为一个 “虚拟文件 “发挥作用。
- 生产进程以及它的所有后代都可以从该管道中读取和写入。这个 “虚拟文件 “或管道可以被一个进程写入,也可以被连接到它的另一个进程读出。
- 如果一个进程试图在任何东西被写入管道之前进行读取,那么它将被停止,直到有任何东西被写入管道。
- 管道的读写端点是由管道系统调用在进程的开放文件表中发现的前两个开放位置决定的。
演示fork()和pipe()的C语言程序
用一个C程序创建两个进程,P1和P2。P1在收到一个字符串后将其交给P2。在不使用字符串函数的情况下,P2将收到的字符串与另一个字符串连接起来,并将结果发回给P1进行打印。
例子。
Other string is: javatpoint.com
Input : www.Javat
Output : www.javatpoint.com
Input : www.tutorialandexamples.com
Output : tutorialandexamples.javatpoint.com
// C program to demonstrate use of fork() and pipe()
#include
#include
#include
#include
#include
#include
int main()
{
// We use two pipes
// First pipe to send input string from parent
// Second pipe to send concatenated string from child
int fd1[2]; // Used to store two ends of first pipe
int fd2[2]; // Used to store two ends of second pipe
char fixed_str[] = "forgeeks.org";
char input_str[100];
pid_t p;
if (pipe(fd1) == -1)
{
fprintf(stderr, "Pipe Failed");
return 1;
}
if (pipe(fd2) == -1)
{
fprintf(stderr, "Pipe Failed");
return 1;
}
scanf("%s", input_str);
p = fork();
if (p < 0)
{
fprintf(stderr, "fork Failed");
return 1;
}
// Parent process
else if (p > 0)
{
char concat_str[100];
close(fd1[0]); // Close reading end of first pipe
// Write input string and close writing end of first
// pipe.
write(fd1[1], input_str, strlen(input_str) + 1);
close(fd1[1]);
// Wait for child to send a string
wait(NULL);
close(fd2[1]); // Close writing end of second pipe
// Read string from child, print it and close
// reading end.
read(fd2[0], concat_str, 100);
printf("Concatenated string %s\n", concat_str);
close(fd2[0]);
}
// child process
else
{
close(fd1[1]); // Close writing end of first pipe
// Read a string using first pipe
char concat_str[100];
read(fd1[0], concat_str, 100);
// Concatenate a fixed string with it
int k = strlen(concat_str);
int i;
for (i = 0; i < strlen(fixed_str); i++)
concat_str[k++] = fixed_str[i];
concat_str[k] = '\0'; // string ends with '\0'
// Close both reading ends
close(fd1[0]);
close(fd2[0]);
// Write concatenated string and close writing end
write(fd2[1], concat_str, strlen(concat_str) + 1);
close(fd2[1]);
exit(0);
}
}
解释一下。
我们利用fork来生成一个子进程()。Fork()返回以下信息。0 创建子(新)进程失败 =0 对于子进程>0,即子进程对父进程的进程ID。当>0时,父进程将运行。
信息可以通过pipe()函数从一个进程发送至另一个进程。由于pipe()是单向的,因此可以设置两个管道,每个方向一个,以提供进程间的双向通信。
在父进程内部: 我们首先关闭第一个管道的读取端(fd1[0]),然后我们通过管道的写入端(fd1[1])写入字符串。父方现在将等待,直到子方的进程完成。子进程结束后,父进程将关闭第二个管道的写入端(fd2[1]),并通过管道的读取端(fd2[0])读取字符串。
在子进程中,子进程通过关闭管道的写入端(fd1[1])读取父进程交付的第一个字符串,读取后将两个字符串连接起来,然后在退出前通过fd2管道将字符串发送到父进程。