进程间通信方式2

进程间通信方式:

1)普通文件

                这种方式基本上所有的教科书上都没有提到过,但是我个人认为这种我们最早接触到的进程间通信的方式;进程可以通过读写同一个文件,并解析文件内的内容来进行通信。

2)管道(pipe)

               管道是以半双工机制来通信的,分为匿名管道和有名管道;匿名管道只能用于有亲缘关系的进程,有名管道能用于有亲缘关系和无亲缘关系的进程。 

[cpp]  view plain  copy
  1. <strong> <span style="font-size:14px;">From manpages</span></strong>  
  2.  #include <unistd.h>  
  3.  int pipe(int pipefd[2]);  
  4.  <strong>Description:</strong>   
  5.          pipe() creates a pipe, a unidirectional data channel that can be used for interpeocess communication. The array pipefd is used to return   
  6.      file descriptors referring to the ends of pipe.  pipefd[0] refers to the read end of pipe. pipefd[1] refers to the read end of the pipe.  
  7.          pipe()创建一个单向的可用于进程间通信的管道, 数组pipefd用来返回指向管道两端的文件描述符. pipefd[0]代表管道读端, pipefd[1]代表管道写端.   
  8.   
  9.  #include <sys/types.h>  
  10.  #include <sys/stat.h>  
  11.  int mkfifo(const char* pathname, mode_t mode)  
  12.  Description:  
  13.       mkfifo() makes a FIFO special file with name pathname. mode specifies the FIFO's permissions. It is modified by the process's umack in the   
  14.  usual way : the permissions of the created file are (mode &~umask).  
  15.       A FILO special file is similar to a pipe, except that it is created in a different way. Instead of being an anonymous communications channel ,  
  16.  a FIFO special file is entered into the filesystem calling mkfife().  
  17.       mkfifo()创建一个名为 pathname 的特殊文件. mode 用来说明文件的权限. 这个权限可实际值为 mode&~umask.  
  18.       除了创建的方式不一样,FIFO特殊文件和管道很类。 FIFE文件通过调用mkfifo()进入文件系统, 而不是通过匿名通道.    
                至于文件描述符的读写,就不在此赘述了!

3)信号(signal)

4)共享内存(shared memory)

[cpp]  view plain  copy
  1. <span style="font-size:14px;"><strong>From manpages</strong></span>  
  2. #include <sys/mman.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5.   
  6. int shm_open(const char* name,  // 文件名  
  7.             int oflag,         // O_RDONLY, O_RDWR等, 和open()标志一样  
  8.             mode_t mode);      // 文件访问权限, 如:0755  
  9.     Return: 成功,则返回文件描述符; 失败, 返回-1.  
  10.   
  11. void *mmap(void* addr,     // 共享内存起始地址   
  12.            size_t length,  // 共享内存长度,字节为单位  
  13.            int prot,       // PROT_EXEC 可执行, PROT_READ 可读, PROT_WRITE 可写, PROT_NONE not be accessed    
  14.            int flags,      // MAP_SHARED | MAP_PRIVATE 一般设为MAP_SHARED   
  15.            int fd,         // shm_open返回的文件描述符  
  16.            off_t offset);  // 偏移  
  17.   
  18. int munmap(void* addr, size_t length);  
  19.   
  20. bsp;int shm_unlink(const char* name);  
  21.   
  22. Link with -lrt  

5)socketpair

[cpp]  view plain  copy
  1.         <strong>From manpages</strong>  
  2.         #include <sys/types.h>  
  3.         #include <sys/socket.h>  
  4.   
  5.         int socketpair(int domain, int type, int protocol, int sv[2])  
  6.         Description:  
  7.              The socketpair() call creates an unnamed pair of connected sockets in the specified domain, of the specified type, and using the optionally   
  8.         specified protocol.  
  9.              socketpair()调用创建一个匿名的,面向连接的socket,通过 domain, type, protocol等参数来说明.  
  10.    

6)socket

通信方式的比较:

1)数据量较大,可以用普通文本文件( 效率低 )和共享内存( 效率高 )实现进程间通信;

2)所有的方式都能在无亲缘关系的进程间通信,socket可以实现不同主机间的进程通信;

3)管道是以半双工的方式工作(可以通过两个管道模拟全双工),socketpair是以全双工的方式工作;

举例:

1)匿名管道(模拟全双工)

[cpp]  view plain  copy
  1. ipc_unnamed_pipe.c------------2016-11-22 20:00---------------------------------  
  2.                  ---Modified--2016-11-23 09:00---------------------------------  
  3.         #include <stdio.h>  
  4.         #include <stdlib.h>  
  5.         #include <unistd.h>  
  6.         #include <string.h>  
  7.   
  8.        int main(int argc, char* argv[])  
  9.        {        
  10.             int  fd_first[2], fd_second[2];  
  11.             if( !(pipe(fd_first) && pipe(fd_second)) ){  
  12.                  perror("pipe");  
  13.                  return -1;  
  14.            }  
  15.   
  16.             pid_t pid = fork();  
  17.             if(pid == 0){          // Child process  
  18.                  close(fd_first[0]);    close(fd_second[1]);  
  19.   
  20.                  char msg[128] = "Hi, parent peocess ...";  
  21.                  write(fd_first[1], msg, strlen(msg) + 1);  
  22.                  memset(msg, 0, sizeof(msg));  
  23.                  read(fd_second[0], msg, sizeof(msg));  
  24.   
  25.                  printf("Message from Parent : %s\n", msg);  
  26.             }else{               // Parent process  
  27.                  close(fd_first[1]);    close(fd_second[0]);  
  28.   
  29.                  char msg[128] = {0};  
  30.                  read(fd_first[0], msg, sizeof(msg));  
  31.                  printf("Message from Child : %s\n", msg);  
  32.            
  33.                  memset(msg, 0, sizeof(msg));  
  34.                  strcpy(msg, "Hi, Child ...");  
  35.                  write(fd_second[1], msg, strlen(msg));  
  36.                  wait(NULL);  
  37.             }  
  38.             return 0;  
  39.        }  

2)有名管道

         

[cpp]  view plain  copy
  1. ipc_fifo_write.c ---------2016-11-23 09:00-----------------------------------------------------  
  2.      #include <stdio.h>  
  3.      #include <stdlib.h>  
  4.      #include <sys/types.h>  
  5.      #include <sys/stat.h>  
  6.        
  7.      int main()  
  8.      {  
  9.            int ret = mkfifo("filename.ff", 0755);  
  10.            if(ret != 0){  
  11.                perror("mkfifo");  
  12.                exit(-1);  
  13.            }  
  14.   
  15.            int fd = open("filename.ff", O_WRONLY);  
  16.            if(fd == -1){  
  17.                perror("open");  
  18.                exit(-1);  
  19.            }  
  20.   
  21.            char msg[128] = "Hello world!";  
  22.            ret = write(fd, msg, strlen(msg) + 1);  // Write to fifo.  
  23.            if(ret < 0){  
  24.                perror("write");  
  25.            }   
  26.              
  27.            close(fd);  
  28.            return 0;  
  29.      }  
  30. bsp;ipc_fifo_read.c -------2016-11-23 09:00------------------------------------------------------------  
  31.      #include <stdio.h>  
  32.      #include <stdlib.h>  
  33.        
  34.      int main()  
  35.      {  
  36.           int fd = open("filename.ff", O_RDONLY);  
  37.           if(fd == -1){  
  38.                perror("open");  
  39.                exit(-1);  
  40.           }  
  41.             
  42.           char msg[128] = {0};  
  43.           int ret = read(fd, msg, sizeof(msg));  
  44.           if(ret > 0){  
  45.                 printf("Message from FIFO : %s\n", msg);  
  46.           }  
  47.           perror("read");  
  48.           close(fd);  
  49.           return 0;  
  50.      }  


3)共享内存

           匿名共享内存:

[cpp]  view plain  copy
  1. ipc_unnamed_shm.c------2016-11-22 20:00------------------------------------------  
  2.       #include <sys/mman.h>  
  3.       #include <sys/stat.h>  
  4.       #include <fcntl.h>  
  5.       #include <stdio.h>  
  6.       #include <stdlib.h>  
  7.       #include <fcntl.h>  
  8.         
  9.       int main()  
  10.       {  
  11.           void* shm = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANOYMOUS, -1,0);  
  12.           if(shm == MAP_FAILED){  
  13.                perror("mmap");  
  14.                return 0;  
  15.           }   
  16.             
  17.           pid_t pid = fork();  
  18.           if(pid == 0){  
  19.                *(int*)shm = 100;  
  20.           }else{  
  21.                sleep(1);  
  22.                printf("From parent : %d\n", *(int*)shm);    
  23.                wait(NULL);  
  24.           }  
  25.           munmap(shm, 1024);  
  26.           return 0;  
  27.       }  
  28. nbsp;  
              有名共享内存

[cpp]  view plain  copy
  1. ipc_shm.c------2016-11-22 20:00-----------------------------------------       
  2.       #include <sys/mman.h>  
  3.       #include <sys/stat.h>  
  4.       #include <fcntl.h>  
  5.       #include <stdio.h>  
  6.       #include <stdlib.h>  
  7.       #include <fcntl.h>  
  8.   
  9.       int main()  
  10.       {  
  11.           int fd = shm_open("/test.shm", O_RDWR, 0755);  
  12.           if(fd < 0){  
  13.               fd = shm_open("/test.shm", O_RDWR | O_CREAT, 0755);  
  14.               if(fd < 0){  
  15.                   perror("shm_open");  
  16.                   return -1;  
  17.               }   
  18.               ftruncate(fd, 4096);  
  19.           }  
  20.             
  21.           char* shm = (char*)mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  
  22.           pid_t pid = fork();  
  23.           if(pid == 0){  
  24.               strcmp(shm, "Hello world\n");  
  25.           }else{  
  26.               sleep(1);  
  27.               printf("From shared memory : %s\n", shm);  
  28.               wait(NULL);  
  29.           }  
  30.           munmap(shm);  
  31.           return 0;  
  32.       }   
              把子进程的代码写在另一个.c文件里,就可以实现无亲缘关系进程间的通信。

 4)socketpair

                 

[cpp]  view plain  copy
  1. ipc_socketpair.c-----2016-11-23 09:00---------------------------------------------------------  
  2.       #include <stdio.h>  
  3.       #include <stdlib.h>  
  4.       #include <sys/socket.h>  
  5.       #include <sys/types.h>  
  6.       #include <unistd.h>  
  7.   
  8.       int main()  
  9.      {  
  10.            int fd[2];  
  11.            int ret = socketpair(AF_UNIX, SOCK_STREAM, 0,fd);  
  12.            if(ret != 0){  
  13.                  perror("socketpair");  
  14.                  return -1;  
  15.            }  
  16.              
  17.            pid_t pid = fork();  
  18.            if(pid == 0){             // Child process  
  19.                  close(fd[1]);  
  20.             
  21.                  int val = 0;  
  22.                  while(1){  
  23.                        sleep(1);  
  24.                        ++val;  
  25.                           
  26.                        write(fd[0], &val, sizeof(val));  
  27.                        read(fd[0], &val, sizeof(val));  
  28.                        printf("Child : %d\n", val);  
  29.                  }  
  30.            }else{                  // Parent process  
  31.                   close(fd[0]);  
  32.   
  33.                   int val;  
  34.                   while(1){  
  35.                         read(fd[1], &val, sizeof(val));  
  36.                         printf("Parent : %d\n", val);  
  37.                         ++val;  
  38.                         write(fd[1], &val, sizeof(val));  
  39.                   }  
  40.            }  
  41.            return 0;  
  42.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值