两个进程如何不通过pipe()来相互交谈?

鉴于此代码:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <unistd.h> #define BUF_SIZE 256 int main() { int fd1[2]; int fd2[2]; ssize_t numRead = -1; // remark : working under the assumption that the messages are of equal length const char* messageOne = "Hello world , I'm child number 1\n"; const char* messageTwo = "Hello world , I'm child number 2\n"; const unsigned int commLen = strlen(messageOne) + 1; char buf[BUF_SIZE]; if (pipe(fd1) == -1) { printf("Error opening pipe 1!\n"); exit(1); } if (pipe(fd2) == -1) { printf("Error opening pipe 2!\n"); exit(1); } printf("Piped opened with success. Forking ...\n"); // child 1 switch (fork()) { case -1: printf("Error forking child 1!\n"); exit(1); case 0: printf("\nChild 1 executing...\n"); /* close reading end of first pipe */ if (close(fd1[0]) == -1) { printf("Error closing reading end of pipe 1.\n"); _exit(1); } /* close writing end of second pipe */ if (close(fd2[1]) == -1) { printf("Error closing writing end of pipe 2.\n"); _exit(1); } /* write to pipe 1 */ if (write(fd1[1], messageOne, commLen) != commLen) { printf("Error writing to pipe 1.\n"); _exit(1); } if (close(fd1[1]) == -1) { printf("Error closing writing end of pipe 1.\n"); _exit(1); } /* reding from pipe 2 */ numRead = read(fd2[0], buf, commLen); if (numRead == -1) { printf("Error reading from pipe 2.\n"); _exit(1); } if (close(fd2[0]) == -1) { printf("Error closing reding end of pipe 2.\n"); _exit(1); } printf("Message received child ONE: %s", buf); printf("Exiting child 1...\n"); _exit(0); break; default: break; } // child 2 switch (fork()) { case -1: printf("Error forking child 2!\n"); exit(1); case 0: printf("\nChild 2 executing...\n"); /* close reading end of second pipe */ if (close(fd2[0]) == -1) { printf("Error closing reading end of pipe 2.\n"); _exit(1); } /* close writing end of first pipe */ if (close(fd1[1]) == -1) { printf("Error closing writing end of pipe 1.\n"); _exit(1); } /* read from the first pipe */ if (read(fd1[0], buf, commLen) == -1) { printf("Error reading from pipe 1.\n"); _exit(EXIT_FAILURE); } if (close(fd1[0]) == -1) { printf("Error closing reading end of pipe 1.\n"); _exit(EXIT_FAILURE); } /* write to the second pipe */ if (write(fd2[1], messageTwo, commLen) != commLen) { printf("Error writing to the pipe."); _exit(EXIT_FAILURE); } if (close(fd2[1]) == -1) { printf("Error closing writing end of pipe 2."); _exit(EXIT_FAILURE); } printf("Message received child TWO: %s", buf); printf("Exiting child 2...\n"); _exit(EXIT_SUCCESS); break; default: break; } printf("Parent closing pipes.\n"); if (close(fd1[0]) == -1) { printf("Error closing reading end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(fd2[1]) == -1) { printf("Error closing writing end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(fd2[0]) == -1) { printf("Error closing reading end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(fd1[1]) == -1) { printf("Error closing writing end of the pipe.\n"); exit(EXIT_FAILURE); } printf("Parent waiting for children completion...\n"); if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } printf("Parent finishing.\n"); exit(EXIT_SUCCESS); } 

这是使用pipe()进行两个进程之间的简单通话。

输出是:

 Piped opened with success. Forking ... Parent closing pipes. Parent waiting for children completion... Child 2 executing... Child 1 executing... Message received child TWO: Hello world , I'm child number 1 Exiting child 2... Message received child ONE: Hello world , I'm child number 2 Exiting child 1... Parent finishing. 

从上面可以看出,两个孩子正在用forkpipe说话。 但是我想这样做而不用pipe道,这是可能的吗? 如果是的话请说明一下,我不想用pipe() ,我想要模拟 pipe()

谢谢

Solutions Collecting From Web of "两个进程如何不通过pipe()来相互交谈?"

我已经修改了您的程序,以显示System V共享内存的示例。 为了避免竞争条件信号量(POSIX命名信号量)也被使用。 我也写了一些评论。 PL。 看看这个例子是否有帮助。 可以参考各个功能的手册页来了解更多关于功能的信息。 编译标志应该是-lpthread。 要生成密钥(引用一个唯一的共享内存段),现有的文件(我已经命名为“anyfile”)应该在当前目录中可用,因为我已经使用了ftok功能。 PL。 通过检查函数的返回值来添加适当的错误处理。

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/shm.h> #include <semaphore.h> #define BUF_SIZE 256 int main() { key_t key; char *virtualaddr; sem_t *get, *put; ssize_t numRead = -1; int shmid; const char* messageOne = "Hello world , I'm child number 1\n"; const char* messageTwo = "Hello world , I'm child number 2\n"; const unsigned int commLen = strlen(messageOne) + 1; char buf[BUF_SIZE]; key = ftok("anyfile",'R'); shmid = shmget(key,1024,0644|IPC_CREAT); if (0 > shmid) { perror("Shared Mem creation error\n"); exit(1); } //Attaching the shared mem to my address space(available across fork) virtualaddr = shmat(shmid, (void*)0, 0); /*Create two POSIX Named Semaphores, get and put and initialising with 0*/ get = sem_open("/get", O_CREAT|O_RDWR, 0644, 0); put = sem_open("/put", O_CREAT|O_RDWR, 0644, 0); // child 1 switch (fork()) { case -1: printf("Error forking child 1!\n"); exit(1); case 0: printf("\nChild 1 executing...\n"); //Referring the semaphores.. get = sem_open ("/get", O_RDWR); put = sem_open ("/put", O_RDWR); //Child 1 writing in shared mem strcpy (virtualaddr, messageOne); //Child 1 signalling that now child 2 can write sem_post (get); //Child1 waiting for Child2 to write.. sem_wait (put); //Child 1 reading from shared mem strcpy (buf, virtualaddr); printf("Message received child ONE: %s", buf); printf("Exiting child 1...\n"); _exit(0); break; default: break; } // child 2 switch (fork()) { case -1: printf("Error forking child 2!\n"); exit(1); case 0: printf("\nChild 2 executing...\n"); //Referring the semaphores.. get = sem_open ("/get", O_RDWR); put = sem_open ("/put", O_RDWR); //Waiting Till Child 1 has written. sem_wait (get); //Now child 2 can read from shared memory strcpy (buf, virtualaddr); //Child 2 writing in shared mem strcpy (virtualaddr,messageTwo ); //Signalling that now Child 1 can read. sem_post (put); printf("Exiting child 2...\n"); printf("Message received child TWO: %s", buf); _exit(EXIT_SUCCESS); break; default: break; } printf("Parent waiting for children completion...\n"); if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } printf("Parent finishing.\n"); //Deleting semaphores.. sem_unlink ("/get"); sem_unlink ("/put"); //Deleting Shared Memory. shmctl (shmid, IPC_RMID, NULL); exit(EXIT_SUCCESS); 

}

虽然为什么你想这样做超出了我的意思,但还有一些其他的IPC机制(更复杂,更容易出错):

  • 命名管道(FIFO)
  • 共享内存
  • 映射的共享内存
  • UNIX域套接字
  • 互联网域套接字

有关这些教程的好教程,请参阅“进程间通信”一章中的电子书: 高级Linux编程

你可以使用共享内存,或者一个Unix套接字。 不知道为什么你会想,但如果管道够了。 shmem和socket都是更低级的。

  1. Unix套接字
  2. 共享内存
  3. CORBA
  4. IPC消息传递(见http://www.cs.cf.ac.uk/Dave/C/node25.html
  5. TCP / IP甚至UDP
  6. 甚至可以写入一个文件,并使用一个信号标志来让另一个进程读取。

就在我头顶