[Linux]进程间通信

前车之鉴, 后车之师

0. 概述

在这里插入图片描述

1. 管道

在这里插入图片描述

1.1.1匿名管道概念

在这里插入图片描述

1.1.2匿名管道代码实现

    1 #include <stdio.h>                                                                                
    2 #include <string.h>
    3 #include <stdlib.h>
    4 #include <unistd.h>
    5 
    6 
    7 int main()
    8 {
    9     // 创建管道
   10     int pipefd[2] = { 0 };
   11     int ret = pipe(pipefd);
   12     if (ret < 0)
   13     {
   14         perror("pipe error");
   15         return -1;
   16     }
   17     
   18     int pid = fork();
   19     if (pid < 0)
   20     {
   21         perror("fork error");
   22         return -1;                                                                                
   23     }
   24     else if (pid == 0)
   25     {
   26         //子进程
   27         char buf[1024] = { 0 };
   28         int ret = read(pipefd[0], buf, 1023);
   29         printf("buf:[%s]-[%d]\n", buf, ret);
   30     }
   31     else
   32     {
   33         //父进程
   34         char* ptr = "今天天气好晴朗";
   35         write(pipefd[1], ptr, strlen(ptr));
   36     }
   37 
   38 
   39 
   40     return 0;
   41 }                 
  • 效果: 子进程读取了父进程的消息

1.2.1命名管道概念

在这里插入图片描述

1.2.2命名管道代码

  • fifo_wirte.c
  1 #include <unistd.h>                                                                                 
  2 #include <stdlib.h> 
  3 #include <stdio.h> 
  4 #include <string.h>
  5 #include <sys/stat.h>
  6 #include <errno.h>
  7 #include <fcntl.h>
  8 
  9 
 10 int main()
 11 {
 12     umask(0);
 13     const char* file = "./test.fifo";
 14     int ret = mkfifo(file, 0664);
 15     if (ret < 0 && errno != EEXIST)
 16     {
 17         perror("mkfifo error");
 18     }
 19     
 20     int fd = open(file, O_WRONLY);
 21     if (fd < 0)
 22     {
 23         perror("open error");
 24         return 0;
 25     }
 26     printf("open fifo success\n");
 27     
 28     while(1)
 29     {
 30         char buf[1024] = {0};
 31         scanf("%s", buf);                                                                           
 32         ret = write(fd, buf, strlen(buf));
 33         if (ret < 0)
 34         {
 35             perror("read error");
 36             return -1;
 37         }
 38     }
 39 
 40     close(fd);
 41     return 0;
 42 }             
  • fifo_read.c
  1 #include <unistd.h>                                                                                 
  2 #include <stdlib.h> 
  3 #include <stdio.h> 
  4 #include <string.h>
  5 #include <sys/stat.h>
  6 #include <errno.h>
  7 #include <fcntl.h>
  8 
  9 
 10 int main()
 11 {
 12     umask(0);
 13     const char* file = "./test.fifo";
 14     int ret = mkfifo(file, 0664);
 15     if (ret < 0 && errno != EEXIST)
 16     {
 17         perror("mkfifo error");
 18     }
  19     
 20     int fd = open(file, O_RDONLY);
 21     if (fd < 0)
 22     {
 23         perror("open error");
 24         return 0;
 25     }
 26     printf("open fifo success\n");
 27     
 28     while(1)
 29     {
 30         char buf[1024] = {0};
 31         ret = read(fd, buf, 1023);                                                                  
 32         if (ret < 0)
 33         {
 34             perror("read error");
 35             return -1;
 36         }
  37         else if(ret == 0)
 38         {
 39             printf("all write close\n");
 40             return -1;
 41         }
 42         printf("buf:[%s]\n", buf);
 43     }
 44 
 45     close(fd);
 46     return 0;
 47 }            
  • makefile
  1 ALL:fifo_write fifo                                                                                 
  2 fifo_write:Fifo_write.c
  3     gcc $^ -o $@
  4 fifo:Fifo.c
  5     gcc $^ -o $@
  • 效果: 在fifo_wirte运行后输入若干字符串, 在fifo_read运行后能够读取并打印字符串

2. 共享内存

在这里插入图片描述

  • 共享内存的操作函数
    在这里插入图片描述
  • 其他特点
    在这里插入图片描述

2.1共享内存代码

  • shm_wirte.c
  1 #include <stdio.h>                                                                                  
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/shm.h>
  5 
  6 
  7 #define IPC_KEY 0x12345678
  8 #define PROJ_ID 0x12345678
  9 // 创建唯一标识
 10 
 11 int main()
 12 {
 13     // 创建共享内存
 14     int shmid = shmget(IPC_KEY, 32, IPC_CREAT|0664);
 15     if (shmid < 0)
 16     {
 17         perror("shmget error");
 18         return -1;
  19     }
 20 
 21     // 映射共享内存
 22     void* shmstart = shmat(shmid, NULL, 0);
 23     if (shmstart == (void*)-1)
 24     {
 25         perror("shmat error");
 26         return -1;
 27     }
 28     while (1)
 29     {
 30         printf("%s", shmstart);
 31         sleep(1);                                                                                   
 32     }
 33     shmdt(shmstart);// 接触映射
 34     shmctl(shmid, IPC_RMID, NULL);// 删除共享内存
 35 
 36     return 0;
 37 }
  • shm_read.c
    1 #include <stdio.h>                                                                                
    2 #include <unistd.h>
    3 #include <stdlib.h>
    4 #include <sys/shm.h>
    5 
    6 
    7 #define IPC_KEY 0x12345678
    8 #define PROJ_ID 0x12345678
    9 // 创建唯一标识
   10 
   11 int main()
   12 {
   13     // 创建共享内存
   14     int shmid = shmget(IPC_KEY, 32, IPC_CREAT|0664);
   15     if (shmid < 0)
   16     {
   17         perror("shmget error");
   18         return -1;
   19     }
   20 
   21     // 映射共享内存
   22     void* shmstart = shmat(shmid, NULL, 0);
   23     if (shmstart == (void*)-1)
   24     {
   25         perror("shmat error");
   26         return -1;
   27     }
   28     int i = 0;
   29     while (1)
   30     {                                                                                             
   31         sprintf(shmstart, "%s-%d\n", "share memory", i++);
   32         sleep(1);
   33     }
   34     shmdt(shmstart);// 接触映射
   35     shmctl(shmid, IPC_RMID, NULL);// 删除共享内存
   36 
   37     return 0;
   38 }           
  • makefile
  1 ALL:shm_read shm_write
  2 shm_write:shm_write.c
  3     gcc $^ -o $@                                                                                    
  4 shm_read:shm_read.c
  5     gcc $^ -o $@
  • 效果: shm_read一直在更新共享内存, shm_write会将共享内存的消息不断打印到屏幕上

3. 消息队列

在这里插入图片描述

4. 信号量

在这里插入图片描述

发布了53 篇原创文章 · 获赞 46 · 访问量 7218

猜你喜欢

转载自blog.csdn.net/new_bee_01/article/details/103496181