IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 进程间通信 -> 正文阅读

[C++知识库]进程间通信

1.管道

管道用来在两个进程之间传递数据。

1.1有名管道

有名管道可以在任意两个进程之间通信
利用mkfifo + 文件名 来促使系统调用创建管道文件

#include <sys/types.h>
#include <sys/stat.h>
//filename 是管道名 mode 是创建的文件访问权限
int mkfifo(const char *filename, mode_t mode)

1.1.1示例1:

进程 a 将从键盘获取的数据循环传递给另一个进程 b

//a.c 从屏幕获取内容写入到管道文件fifo中
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <unistd.h>
  5 #include <fcntl.h>
  6 #include <assert.h>
  7 int main()
  8 {
  9     int fd=open("fifo",O_WRONLY);
 10     assert(fd!=-1);
 11 
 12     while(1)
 13     {
 14         char buff[128]={0};
 15         fgets(buff,128,stdin);
 16         write(fd,buff,strlen(buff)-1);
 17         if(strncmp(buff,"end",3)==0)
 18         {
 19             break;
 20         }
 21     }
 22     close(fd);
 23     exit(0);
//b.c 从管道文件fifo中读取内容输出到屏幕
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <assert.h>
  5 #include <fcntl.h>
  6 #include <string.h>
  7 int main()
  8 {
  9     int fd=open("fifo",O_RDONLY);
 10     assert(fd!=-1);
 11 
 12     while(1)
 13     {
 14         char buff[128]={0};
 15         int n=read(fd,buff,128);
 16         if(n<=0)
 17         {
 18             break;
 19         }
 20         printf("%s\n",buff);
 21     }
 22     close(fd);
 23     exit(0);
 24 }

程序运行结果:
(打开两个会话窗口,同时运行a,b两个程序)
在这里插入图片描述

1.2无名管道

无名管道主要用于父子进程间的通信
无名管道的创建如下:

#include <unistd.h>

int pipe(int fds[2]);
/*
pipe()成功返回 0,失败返回-1
fds[0]是管道读端的描述符
fds[1]是管道写端的描述符
*/

1.2.1示例2:

父进程向管道中写入内容,子进程从管道中读取内容并输出到屏幕

  1 #include <stdlib.h>
  2 #include <fcntl.h>
  3 #include <string.h>
  4 #include <stdio.h>
  5 #include <unistd.h>
  6 #include <assert.h>
  7 int main()
  8 {
  9     int fd[2];
 10     int res=pipe(fd);
 11     assert(res!=-1);
 12     pid_t pid=fork();
 13     assert(pid!=-1);
 14     if(pid==0)//子进程读
 15     {
 16         char buff[128]={0};
 17         read(fd[0],buff,strlen(buff)-1);
 18         printf("%s\n",buff);
 19     }
 20     else
 21     {//父进程写
 22         char buff[128]={0};
 23         fgets(buff,128,stdin);
 24         write(fd[1],buff,strlen(buff)-1);
 25     }
 26 
 27     close(fd[0]);
 28     close(fd[1]);
 29     exit(0);
 30 }

程序运行结果:
在这里插入图片描述

1.3管道的特点:

①写入管道的数据都在内存中
②管道是一种半双工通信方式
③有名可以在任意进程间使用,而无名主要在父子进程间

2.信号量

用于管理对资源的访问
信号量是一种特殊的变量,只允许对它进行等待和发送信号这两种操作。
P(信号量变量):用于等待。(对信号量变量进行-1操作)
V(信号量变量):用于发送信号。(对信号量变量进行+1操作)

2.1信号量的接口介绍

2.1.1semget函数

用于创建或者获取已存在的信号量
成功时返回信号量标识符,失败返回-1

int semget(key_t key,int num_sems,int sem_flags)

第一个参数:是整数值,不相关的进程可以通过key来访问同一个信号量。返回一个信号量的标识符,以供其他的信号量函数使用。
第二个参数:指定需要的信号量数目
第三个参数:作用类似于创建文件的时候所设置的文件访问权限。我们可以联合使用标志IPC_CREAT和IPC_EXCL来创建一个新的、唯一的信号量。也可以在“或”操作设置权限
例如:semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);

2.1.2semop函数

用于对信号量进行改变P/V操作
成功返回0,失败返回-1

int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_ops);

第一个参数:是由semget返回的信号量标识符
第二个参数:指向一个结构数组的指针,这个数组成员如下:

struct sembuf
{
    short sem_num;//信号量的编号,表示这个第几个信号量,编号从0开始
    short sem_op;//设置为-1表示p操作,设置为1表示v操作
    short sem_flg;//设置为SEM_UNDO,从而使得这个进程在没有释放信号量的情况下终止后,操作系统将会自动释放该进程所持有的信号量
}

第三个参数:一般写为1

2.1.3semctl函数

控制信号量
成功返回0,失败返回-1

int semctl(int sem_id,int sem_num,int command,...)

第一个参数:是由semget返回的信号量标识符
第二个参数:信号量的编号,表示这个第几个信号量,编号从0开始
第三个参数:表示将要采取的动作,有以下两个常用的:
①SETVAL:用来把信号量初始化为一个已知的值,这个值通过union_semun中的val成员设置。
②IPC_RMID:用于删除一个已经无需继续使用的信号量标识符
第四个参数:如果第三个参数被设置为SETVAL,那么第四个参数将会是一个union_semun结构。至少有一下成员:

union semun
{
   int val;//设置信号量的初始值
   struct semid_ds *buf;
   unsigned short *array;
}

2.2 信号量的使用

2.2.1 示例3(使用一个信号量的例子):

进程 a 和进程 b 模拟访问打印机,进程 a 输出第一个字符‘a’表示开始使用打印机,输出第二个字符‘a’表示结束使用,b 进程操作与 a 进程相同。(由于打印机同一时刻只能被一个进程使用,所以输出结果不应该出现 abab)

//ab.h
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <assert.h>
  4 #include <sys/sem.h>
  5 union semun
  6 {
  7     int val;
  8 };
  9 int sem_init();
 10 void sem_p();
 11 void sem_v();
 12 void sem_destory();

  1 #include "ab.h"
  2 
  3 static int semid=-1;
  4 int sem_init()
  5 {
  6     semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
  7     if(semid==-1)//如果获取失败
  8     {
  9         semid=semget((key_t)1234,1,0600);//获取可能已经创建好的semid
 10         if(semid==-1)//还是失败就输出错误并返回
 11         {
 12             printf("semget err\n");
 13             return -1;
 14         }
 15     }
 16     else//获取成功,然后进行设置
 17     {
 18         union semun a;
 19         a.val=1;
 20         if(semctl(semid,0,SETVAL,a)==-1)
 21         {
 22             printf("semctl err\n");
 23             return -1;
 24         }
 25     }
 26 }
 27 void sem_p()
 28 {
 29     struct sembuf buf;
 30     buf.sem_num=0;
 31     buf.sem_op=-1;
 32     buf.sem_flg=SEM_UNDO;
 33     if(semop(semid,&buf,1)==-1)
 34     {
 35         printf("sem_p err\n");
 36     }
 37 }
 38 void sem_v()
 39 {
 40     struct sembuf buf;
 41     buf.sem_num=0;
 42     buf.sem_op=1;
 43     buf.sem_flg=SEM_UNDO;
 44     if(semop(semid,&buf,1)==-1)
 45     {
 46         printf("sem_v err\n");
 47     }
 48 
 49 }
 50 void sem_destory()
 51 {
 52     if(semctl(semid,0,IPC_RMID)==-1)
 53     {
 54         printf("sem_destory err\n");
 55     }
 56 }
//a程序
  1 #include <unistd.h>
  2 #include "ab.h"
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 int main()
  6 {
  7     sem_init();
  8     for(int i=0;i<10;++i)
  9     {
 10         sem_p();
 11         printf("a");
 12         fflush(stdout);
 13         int n=rand()%3;
 14         sleep(n);
 15         printf("a");
 16         fflush(stdout);
 17         sem_v();
 18         n=rand()%3;
 19         sleep(n);
 20     }
 21     return 0;
 22 }

  1 #include <unistd.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include "ab.h"
  5 int main()
  6 {
  7     sem_init();
  8     for(int i=0;i<10;++i)
  9     {
 10          sem_p();
 11          printf("b");
 12          fflush(stdout);
 13          int n=rand()%3;
 14          sleep(n);
 15          printf("b");
 16          fflush(stdout);
 17          sem_v();
 18          n=rand()%3;
 19          sleep(n);
 20      }
 21      return 0;
 22 }
 23 

程序运行结果:
在这里插入图片描述

2.2.2 示例4(使用三个信号量的例子):

:三个进程 a、b、c 分别输入“A”、“B”、“C”,要求输出结果必须是“ABCABCABC…”

//sem.h
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <assert.h>
  4 #include <sys/sem.h>
  5 #define SEM_NUM 3//2个信号量
  6 #define SEM1 0//第一个信号量的编号为0
  7 #define SEM2 1//第二个信号量的编号为1
  8 #define SEM3 2//第三个信号量的编号为2
  9 union semun
 10 {
 11      int val;
 12 };
 13 int sem_init();
 14 void sem_p(int index);
 15 void sem_v(int index);
 16 void sem_destory();
 17 

//sem.c
  1 #include "sem.h"
  2 static int semid=-1;
  3 int sem_init()
  4 {
  5    semid=semget((key_t)1235,SEM_NUM,IPC_CREAT|IPC_EXCL|0600);
  6    if(semid==-1)//如果获取失败
  7    {
  8       semid=semget((key_t)1235,SEM_NUM,0600);//获取可能已经创建好的semid
  9       if(semid==-1)//还是失败就输出错误并返回
 10       {
 11           printf("semget err\n");
 12           return -1;
 13       }
 14     }
 15     else//获取成功,然后进行设置
 16     {
 17         int arr[SEM_NUM]={1,0,0};
 18         for(int i=0;i<SEM_NUM;++i)
 19         {
 20            union semun a;
 21            a.val=arr[i];
 22            if(semctl(semid,i,SETVAL,a)==-1)
 23            {
 24               printf("semctl err\n");
 25               return -1;
 26            }
 27         }
 28     }
 29 }
 30 void sem_p(int index)
 31 {
 32    if(index<0||index>=SEM_NUM)
 33    {
 34        return;
 35    }
 36    struct sembuf buf;
 37    buf.sem_num=index;
 38    buf.sem_op=-1;
 39    buf.sem_flg=SEM_UNDO;
 40 
 41    if(semop(semid,&buf,1)==-1)
 42    {
 43        printf("sem_p err\n");
 44        return ;
 45    }
 46 }
 47 void sem_v(int index)
 48 {
 49     if(index<0||index>=SEM_NUM)
 50     {
 51         return;
 52     }
 53     struct sembuf buf;
 54     buf.sem_num=index;
 55     buf.sem_op=1;
 56     buf.sem_flg=SEM_UNDO;
 57 
 58     if(semop(semid,&buf,1)==-1)
 59     {
 60         printf("sem_v err\n");
 61         return;
 62     }
 63 }
 64 void sem_destory()
 65 {
 66     if(semctl(semid,0,IPC_RMID)==-1)
 67     {
 68         printf("sem_destroy err\n");
 69         return;
 70     }
 71 }

//a.c
  1 #include <stdio.h>
  2 #include "sem.h"
  3 #include <unistd.h>
  4 int main()
  5 {
  6     int res=sem_init();
  7     if(res==-1)
  8     {
  9         return 0;
 10     }
 11     for(int i=0;i<5;++i)
 12     {
 13         sem_p(SEM1);
 14         printf("a");
 15         fflush(stdout);
 16         sem_v(SEM2);
 17     }
 18 
 19 //    sem_destory();
 20 
 21     return 0;
 22 }

//b.c
  1 #include <stdio.h>
  2 #include "sem.h"
  3 #include <unistd.h>
  4 int main()
  5 {
  6      int res=sem_init();
  7      if(res==-1)
  8      {
  9          return 0;
 10      }
 11      for(int i=0;i<5;++i)
 12      {
 13          sem_p(SEM2);
 14          printf("b");
 15          fflush(stdout);
 16          sem_v(SEM3);
 17      }
 18 
 19      //sem_destory();
 20 
 21      return 0;
 22  }
 23 

//c.c
  1 #include <unistd.h>
  2 #include <stdio.h>
  3 #include "sem.h"
  4 int main()
  5 {
  6     int res=sem_init();
  7     if(res==-1)
  8     {
  9         return 0;
 10     }
 11 
 12     for(int i=0;i<5;++i)
 13     {
 14         sem_p(SEM3);
 15         printf("c");
 16         fflush(stdout);
 17         sem_v(SEM1);
 18     }
 19 
 20     sem_destory();
 21     return 0;
 22 }

程序运行结果:
在这里插入图片描述

3.共享内存

用于在程序之间高效地共享数据
共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。

共享内存为在多个进程之间共享和传递数据提供了一种有效的方式,因为它并未提供同步机制,所以我们通常需要用信号量来同步对共享内存的访问。

3.1共享内存的接口介绍

3.1.1shmget函数

用于创建或者获取共享内存
成功返回共享内存标识符,失败返回-1

int shmget(key_t key,size_t size,int shmflg);

第一个参数:提供一个参数key,有效的为共享内存段命名。shmget函数返回一个共享内存标识符,用于后续的共享内存函数。
第二个参数:以字节为单位指定需要共享的内存容量。
第三个参数:设置权限。由IPC_CREAT和权限标志或才能创建一个新的共享内存段。

3.1.2shmat函数

将申请的共享内存的物理内存映射到当前进程的虚拟地址空间上
成功返回一个指向共享内存第一字节的指针,失败返回-1

void* shmat(int shm_id,const void* shm_addr,int shmflg)

第一个参数:由shmget返回的共享内存标识符
第二个参数:指定的是共享内存连接到当前进程中的地址位置,通常是一个空指针,表示让系统来选择共享内存出现的地址。
第三个参数:一组位标志。两个可能取值如下:
①SHM_RND:这个标志和shm_addr联合使用,用来控制共享内存链接的地址
②SHM_RDONLY:它使得连接的内存只读。

3.2.3shmdt函数

shmdt()断开当前进程的shmaddr指向的共享内存映射
成功返回0,失败返回-1

int shmdt(const void* shmaddr)

第一个参数:是shmat()函数返回的地址指针

3.2.4shmctl函数

shmctl()控制共享内存
成功返回0,失败返回-1

int shmctl(int shm_id,int command,struct shmid_ds *buf);

第一个参数:是shmget返回的共享内存标识符
第二个参数:要采取的工作,它可以取三个值:
①IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值
②IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
③IPC_RMID:删除共享内存段
第三个参数:buf是一个指针,它指向包含共享内存模式和访问权限的结构
struct shmid_ds结构至少包含以下成员:

struct shmid_ds
{
    uid_t shm_perm.uid;
    uid_t shm_perm.gid;
    mode_t shm_perm.mode;
}

3.2共享内存的使用

3.2.1示例5:

进程 a 向共享内存中写入数据,进程 b 从共享内存中读取数据并显示

//a.c
  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <assert.h>
  4 #include <stdlib.h>
  5 #include <sys/shm.h>
  6 #include <string.h>
  7 int main()
  8 {
  9     //创建共享内存
 10     int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
 11     assert(shmid!=-1);
 12 
 13     //将共享内存映射到当前的进程中
 14     char* s=shmat(shmid,NULL,0);
 15     assert(s!=NULL);
 16 
 17     strcpy(s,"hello");
 18 
 19     shmdt(s);
 20 
 21     return 0;
 22 }

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <assert.h>
  4 #include <string.h>
  5 #include <unistd.h>
  6 #include <sys/shm.h>
  7 int main()
  8 {
  9     int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
 10     assert(shmid!=-1);
 11 
 12     char*s =shmat(shmid,NULL,0);
 13     assert(s!=NULL);
 14 
 15     printf("%s\n",s);
 16 
 17     shmdt(s);
 18 
 19     shmctl(shmid,IPC_RMID,NULL);
 20 
 21     return 0;
 22 }

程序运行结果:
在这里插入图片描述

3.2.2示例6:

进程 a 从键盘循环获取数据并拷贝到共享内存中,进程 b 从共享内存中获取并打印数据。进程 a 输入一次,进程 b 输出一次,进程 a 不输入,进程 b 也不输出。

//sem.h
  1 #include <unistd.h>
  2 #include <stdio.h>
  3 #include <assert.h>
  4 #include <sys/sem.h>
  5 #include <sys/shm.h>
  6 #include <string.h>
  7 #include <stdlib.h>
  8 union semun
  9 {
 10     int val;
 11 };
 12 #define SEM_W 0
 13 #define SEM_R 1
 14 int sem_init(int key,int sembuf[],int semmum);
 15 int sem_p(int semid,int index);
 16 int sem_v(int semid,int index);
 17 int sem_destory(int semid);

//sem.c
  1 #include "sem.h"
  2 int sem_init(int key,int sembuf[],int semnum)
  3 {
  4     int semid=semget((key_t)key,semnum,0664);
  5     if(semid==-1)
  6     {
  7         semid=semget((key_t)key,semnum,IPC_CREAT|0664);
  8         if(semid==-1)
  9         {
 10             printf("semget err\n");
 11             return 0;
 12         }
 13     }
 14     else
 15     {
 16         for(int i=0;i<semnum;++i)
 17         {
 18             union semun a;
 19             a.val=sembuf[i];
 20             if(semctl(semid,i,SETVAL,a)==-1)
 21             {
 22                 printf("semctl err\n");
 23                 return -1;
 24             }
 25         }
 26     }
 27     return semid;
 28 }
 29 int sem_p(int semid,int index)
 30 {
 31     struct sembuf buf;
 32     buf.sem_num=index;
 33     buf.sem_op=-1;
 34     buf.sem_flg=SEM_UNDO;
 35 
 36     if(semop(semid,&buf,1)==-1)
 37     {
 38         printf("semop err\n");
 39         return -1;
 40     }
 41     return 0;
 42 }
 43 int sem_v(int semid,int index)
 44 {
 45     struct sembuf buf;
 46     buf.sem_num=index;
 47     buf.sem_op=1;
 48     buf.sem_flg=SEM_UNDO;
 49 
 50     if(semop(semid,&buf,1)==-1)
 51     {
 52         printf("semop err\n");
 53         return -1;
 54     }
 55     return 0;
 56 }
 57 int sem_destory(int semid)
 58 {
 59     if(semctl(semid,0,IPC_RMID)==-1)
 60     {
 61         printf("sem_destory err\n");
 62         return -1;
 63     }
 64     return 0;
 65 }
//read.c
  1 #include "sem.h"
  2 int main()
  3 {
  4     int shmid=shmget((key_t)1357,128,IPC_CREAT|0664);
  5     assert(shmid!=-1);
  6 
  7     char* s=shmat(shmid,NULL,0);
  8     assert(s!=NULL);
  9 
 10     int sembuf[]={1,0};
 11     int semid=sem_init(1000,sembuf,2);
 12 
 13     while(1)
 14     {
 15         sem_p(semid,SEM_R);
 16         if(strncmp(s,"end",3)==0)
 17         {
 18             break;
 19         }
 20         printf("%s",s);
 21         sem_v(semid,SEM_W);
 22     }
 23     shmdt(s);
 24     shmctl(shmid,IPC_RMID,NULL);
 25     sem_destory(semid);
 26     return 0;
 27 }

  1 #include "sem.h"
  2 int main()
  3 {
  4     int shmid=shmget((key_t)1357,128,IPC_CREAT|0664);
  5     assert(shmid!=-1);
  6 
  7     char* s=shmat(shmid,NULL,0);
  8     assert(shmat!=NULL);
  9 
 10     int sembuf[]={1,0};
 11     int semid=sem_init(1000,sembuf,2);
 12 
 13     while(1)
 14     {
 15         printf("请输入:\n");
 16         char buff[128]={0};
 17         fgets(buff,128,stdin);
 18 
 19         sem_p(semid,SEM_W);
 20         strcpy(s,buff);
 21         sem_v(semid,SEM_R);
 22 
 23         if(strncmp(buff,"end",3)==0)
 24         {
 25             break;
 26         }
 27     }
 28 
 29     shmdt(s);
 30     shmctl(shmid,IPC_RMID,NULL);
 31     return 0;
 32 
 33 }

程序运行结果:
在这里插入图片描述

4、消息队列

在程序之间传递数据地一种简单方法

4.1消息队列的接口介绍

4.1.1msgget函数

用来创建和访问一个消息队列
成功返回一个正整数,失败返回-1

int msgget(key_t key,int msgflg);

第一个参数:提供一个键值来命名某个特定的队列
第二个参数:设置权限,由IPC_CREAT定义的一个特殊位必须和权限标志位或才能创建一个新的消息队列,如果消息队列已有,则IPC_CREAT标志就会被悄悄忽略掉。

4.1.2msgsnd函数

用来把消息添加到消息队列中
成功返回0,失败返回-1

int msgsnd(int msqid,const void *msg_ptr,size_t msg_sz,int msgflg);

第一个参数:由msgget函数返回的消息队列队列标识符
第二个参数:指向准备发送消息的指针。
消息的结构为:

struct msgbuf
{
     long mtype;//消息类型,必须大于0
     char mtext[1];//消息数据
};

第三个参数:msg_ptr指向的消息的长度
第四个参数:控制在当前消息队列满或队列消息达到系统范围的限制时将要发生的事情。如果设置IPC_NOWAIT的标志,函数将立刻返回,不发送消息并且返回值为-1,如果msgflg中IPC_NOWAIT标志被清除,则发送进程将被挂起以等待队列中腾出可用空间。

4.1.3msgrcv函数

从消息队列中获取消息
成功时返回放到接收缓冲区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的消息。失败返回-1 。

int msgcrv(int msqid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflg);

第一个参数:消息队列标识符
第二个参数:指向准备接收消息的指针
第三个参数:msg_ptr指向的消息长度
第四个参数:实现接收优先级。
msgtype=0:获取队列中的第一个可用消息
msgtype>0:获取具有相同消息类型的第一个消息
msgtype<0:获取消息类型等于或小与msgtype的绝对值的第一个消息。
第五个参数:用于控制当队列中没有相应类型的消息可以接收时将发生的事情。

4.1.4msgctl函数

控制消息队列
成功返回0,失败返回-1

int msgctl(int msqid,int command,struct msqid_ds *buf);

第一个参数:消息队列标识符
第二个参数:将要采取的动作
①IPC_STAT:把msqid_ds结构中的数据设置为消息队列的当前关联值
②IPC_SET:如果进程有足够的权限,九八消息队列的当前关联值设置为msqid_ds结构中给出的值
③IPC_RMID:删除消息队列
第三个参数:

struct msqid_ds{
   uid_t msg_perm.uid;
   uid_t msg_perm.gid;
   mode_t msg_perm.mode;
}

4.2消息队列的使用

4.2.1示例7:

进程 a 发送一条消息,进程 b 读取消息。

//a.c
  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <assert.h>
  4 #include <string.h>
  5 #include <sys/msg.h>
  6 typedef struct my_message
  7 {
  8     long mytype;//消息类型
  9     char mytext[128];//消息数据
 10 }myssage;
 11 int main()
 12 {
 13     int msgid=msgget((key_t)2468,IPC_CREAT|0664);
 14     assert(msgid!=-1);
 15 
 16     myssage data;
 17     memset(&data,0,sizeof(data));
 18     data.mytype=1;
 19     strcpy(data.mytext,"hello");
 20 
 21     msgsnd(msgid,&data,128,0);
 22 
 23     return 0;
 24 }

//b.c
  1 #include <stdio.h>
  2 #include <assert.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #include <sys/msg.h>
  6 #include <unistd.h>
  7 typedef struct my_myssage
  8 {
  9     long mytype;
 10     char mytext[128];
 11 }myssage;
 12 int main()
 13 {
 14     int msgid=msgget((key_t)2468,IPC_CREAT|0664);
 15     assert(msgid!=-1);
 16 
 17     myssage data;
 18     memset(&data,0,sizeof(data));
 19 
 20     msgrcv(msgid,&data,128,1,0);//获取1这个特定类型的第一个消息
 21     printf("%ld\n",data.mytype);
 22     printf("%s\n",data.mytext);
 23 
 24     msgctl(msgid,IPC_RMID,NULL);
 25     return 0;
 26 
 27 }

程序运行结果:
在这里插入图片描述

5.ipcs\ipcrm

ipcs可以查看消息队列、共享内存、信号量的使用情况
ipcrm可以进行删除操作

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:30:33  更:2022-02-09 20:31:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:25:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码