c - 如何创建 IPC(进程间通信)C 程序来创建两个子进程

标签 c

我想创建一个 IPC c 程序来创建一个父进程和两个子进程。我的代码是:

#include <stdio.h>
void main()
{
    int pid, status;
    pid = fork();
    if(pid == -1) {
        printf(“fork failed\n”);
        exit(1);
    }
    if(pid == 0) { /* Child */
        if (execlp(“/bin/ls”, “ls”, NULL)< 0) {
            printf(“exec failed\n”);
            exit(1);
        }
    }
    else { /* Parent */
        wait(&status);
        printf(“Well done kid!\n”);
        exit(0);
    }
}

我想向您展示另一个代码片段来创建一个父进程和两个子进程。这就是我正在寻找的。现在我想写IPC的shell脚本,先看一下这段代码。

注意:还有一个具有相同逻辑但不同进程名称 UP、uc1、uc2 的代码,例如,这样我们就有两个父 VP 和 UC,并且有子代 vp1 vp2 和 uc1 uc2。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_BUF 1024

int main(){

int mypipe_c1[2];
int ret_c1;
char buf_c1[6];

ret_c1 =pipe(mypipe_c1);

int mypipe_c2[2];
int ret_c2;
char buf_c2[6];

ret_c2 =pipe(mypipe_c2); 

if(ret_c1 == -1)
{
    perror("pipe");
    exit(1);
}

pid_t vc1;


pid_t vc2; 

  vc1 = fork ();
  if (vc1 == 0)
  {
read(mypipe_c1[0], buf_c1 , 37);
        printf("PIPE1 :%s\n", buf_c1);
    printf (" vc1 : I'm the child!  My pid is (%d)\n", getpid ());
close(ret_c1);

int fd;
    char * fifo1 = "/tmp/fifo1";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(fifo1, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("FIFO1: %s\n", buf);
    close(fd);
exit(0);
  }
  if(vc1 < 0)
  {
    perror ("Ouch!  Unable to fork() child process!\n");
    exit (1);
  }

 vc2 = fork ();
   if (vc2 == 0)
  {
    printf ("vc2 : I'm the child!  My pid is (%d)\n", getpid ());
read(mypipe_c2[0], buf_c2 , 37);
   printf("PIPE2 %s\n", buf_c2);

int fd;
    char * fifo2 = "/tmp/fifo2";

    /* create the FIFO (named pipe) */
    mkfifo(fifo2, 0666);

    /* write "Hi" to the FIFO */
    fd = open(fifo2, O_WRONLY);
    write(fd, " assignment VU 2 ", sizeof(" assignment VU 2 "));
    close(fd);

    /* remove the FIFO */
    unlink(fifo2);
exit(0);
  }
  else if (vc2 < 0)
  {
    perror ("Ouch!  Unable to fork() child process!\n");
    exit (1);
  }
printf ("I'm the parent! My pid is  (%d)!\n",getpid());
write(mypipe_c1[1], "I am going to close you carry on UC1 \n", 37);
write(mypipe_c2[1], "I am going to close you carry on UC2 \n", 37);

exit(0);
}

现在我想要 shell 脚本,以便当用户键入 … script.sh start VP 或 UP 时应该启动 VP 和 UP。 vc1、vc2、uc1、uc2 只能使用 script.sh stop vc1 或 vc2 或 uc1 或 uc2 来停止

script.sh connect 命令应创建两个 fifo 和连接进程,如图所示。

Image

最佳答案

所以你要求IPC的方法,根据你提供的示例代码,我认为最好的方法是使用管道。

来自 pipe() 手册页:

A pipe is a unidirectional data channel that can be used for interprocess communication

基本上,它的处理方式就像一对文件描述符。首先,您必须初始化管道,然后使用 fork() 调用创建子管道,以便父管道和子管道共享资源。然后,使用 writeread 方法,您可以在它们之间发送数据。

在此示例中,我创建一个子进程,它从父进程读取一些数据:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
    int pid;
    char buffer[255];
    int fd[2]; // channel 0 for reading and 1 for writing
    pipe(fd);
    pid = fork();
    if(pid == 0) {
        close(fd[1]); // close fd[1] since child will only read
        read(fd[0], &buffer, sizeof(buffer));
        close(fd[0]);
        exit(0);
    } else { // parent
        close(fd[0]) // close fd[0] since parent will only write
        // init buffer contents
        write(fd[1], &buffer, sizeof(buffer));
        close(fd[1]);
    }
    return 0;
}

正如你所看到的,pipe 创建了一对文件描述符,一个用于写入(编号 1),一个用于读取(编号 0)。

在我的示例代码中,子进程关闭写入进程,因为它只会读取,而父进程关闭读取进程,因为它只会写入数据。

请注意,管道是单向的,因此如果您希望子级和父级都从中写入和读取数据,则应为每个子级创建两个管道(即 4 个文件描述符)。如何处理这种情况的示例:

int pipeA[2], pipeB[2];
pid = fork();
if (pid == 0) { // child will write to pipeB and read from pipeA
    close(pipeA[1]); // closing pipeA writing fd
    close(pipeB[0]); // closing pipeB reading fd
    write(pipeB[1],&buffer, sizeof(buffer));
    read(pipeA[0], &buffer2, sizeof(buffer2));
    close(pipeA[0]);
    close(pipeB[1]);
    exit(1);
} else { // parent will write to pipeA and read from pipeB
    close(pipeA[0]); // closing pipeA reading fd
    close(pipeB[1]); // closing pipeB writing fd
    read(pipeB[0], &buffer, sizeof(buffer));
    write(pipeA[1], &buffer2, sizeof(buffer2));
    close(pipeA[1]);
    close(pipeB[0]);
}

如果您想了解有关管道的更多信息,您可以查看手册页 here

此外,IPC 的其他简单方法是使用 Unix Sockets ,尽管我认为对于这个例子,你提供的管道就足够了。

关于c - 如何创建 IPC(进程间通信)C 程序来创建两个子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44111607/

相关文章:

c - 没有从 fgets() 函数获得预期的输出

c++ - 无法使用 C++ 语法运行 Opencv

c - 如何从 Objective-C 方法返回 C 指针引用?

c - 在缓冲区中搜索十六进制值并返回 C 中的结果位置

c - 如何解决c中的冲突类型错误?

c - pthread_mutex_init 与 sem_init(非共享)

c - malloc 失败?

c - 在 C 中读取计算器的字符串输入

c - 读取数据并使用 scanf 跳过括号

C 代码 : Efficient way to parse through to end of LinkedList