上边的话说哪些用不用新闻队列来展开进程间的通讯,音讯队列与命名管道有成都百货上千相似之处。有关命名管道的更加多内容能够参见笔者的另一篇文章:Linux进度间通讯——使用命名管道

上边包车型地铁话说如何用不用音讯队列来展开进程间的通讯,新闻队列与命名管道有诸多相似之处。有关命名管道的越来越多内容能够参照笔者的另一篇小说:Linux进度间通讯——使用命名管道

上面包车型客车话说哪些用不用消息队列来开始展览进程间的通讯,音讯队列与命名管道有那个相似之处。有关命名管道的越来越多内容能够参考笔者的另一篇文章:Linux进度间通讯——使用命名管道

Linux进度间通讯——使用消息队列,linux进度消息队列

上边的话说哪些用不用音信队列来展开进度间的通讯,新闻队列与命名管道有为数不少相似之处。有关命名管道的更加多内容能够参照小编的另一篇文章:Linux进度间通讯——使用命名管道
  一 、什么是音信队列
音讯队列提供了一种从贰个历程向另三个进程发送二个数据块的章程。
 种种数据块都被认为包罗三个连串,接收进程能够独自地选用含有不相同类其他数据结构。大家得以由此发送新闻来制止命名管道的联合和堵塞问题。然则音信队列与命名管道一样,每一种数据块都有二个最大尺寸的界定。
  Linux用宏MS创新霉素AX和MSGMNB来界定一条信息的最大尺寸和3个行列的最大尺寸。
  二 、在Linux中应用新闻队列
Linux提供了一层层音信队列的函数接口来让大家有利地利用它来促成进度间的通信。它的用法与任何七个System
V PIC机制,即信号量和共享内部存款和储蓄器相似。   壹 、msgget函数
该函数用来成立和做客二个新闻队列。它的原型为: [cpp] view
plain copy    print?

  1. int msgget(key_t, key, int msgflg);  

与任何的IPC机制一样,程序必须提供一个键来命名某些特定的音讯队列。msgflg是3个权力标志,表示新闻队列的拜会权限,它与公事的拜会权限一样。msgflg能够与IPC_CREAT做或操作,表示当key所命名的新闻队列不设有时创制多少个音讯队列,借使key所命名的新闻队列存在时,IPC_CREAT标志会被忽视,而只回去一个标识符。
  它回到一个以key命名的消息队列的标识符(非零整数),战败时重返-1.  
② 、msgsnd函数 该函数用来把音讯添加到音信队列中。它的原型为:
[cpp] view plain copy    print?

  1. int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);  

msgid是由msgget函数再次回到的新闻队列标识符。  
msg_ptr是三个针对性准备发送音讯的指针,可是音信的数据结构却有必然的渴求,指针msg_ptr所指向的新闻结构自然假如以一个长整型成员变量起先的结构体,接收函数将用那些成员来规定音信的种类。所以音讯结构要定义成这么:
  [cpp] view plain copy    print?

  1. struct my_message{  
  2.     long int message_type;  
  3.     /* The data you wish to transfer*/  
  4. };  

msg_sz是msg_ptr指向的音讯的长短,注意是音讯的长度,而不是百分百结构体的长度,也正是说msg_sz是不蕴含长整型新闻类型成员变量的尺寸。
 
msgflg用于控制当前新闻队列满或队列音信到达系统范围的限量时就要发生的事情。
 
要是调用成功,新闻数据的一分副本将被内置音讯队列中,并再次回到0,退步时重返-1.
  三 、msgrcv函数 该函数用来从二个音信队列获取音信,它的原型为
[cpp] view plain copy    print?

  1. int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);  

msgid, msg_ptr, msg_st的机能也函数msgsnd函数的均等。  
msgtype能够达成一种不难的收取优先级。假诺msgtype为0,就赢得队列中的第3个新闻。假使它的值大于零,将赢得具有相同新闻类型的首先个音讯。假设它小于零,就拿走项目等于或小于msgtype的相对值的第一个消息。
  msgflg用于控制当队列中从不相应类其他新闻能够接到时将产生的业务。  
调用成功时,该函数返重放到接收缓存区中的字节数,信息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除音信队列中的对应音讯。失利时回来-1.
  肆 、msgctl函数
该函数用来决定新闻队列,它与共享内部存款和储蓄器的shmctl函数相似,它的原型为:
[cpp] view plain copy    print?

  1. int msgctl(int msgid, int command, struct msgid_ds *buf);  

command是即将利用的动作,它能够取贰个值,  
  IPC_STAT:把msgid_ds结构中的数据设置为新闻队列的眼下关系值,即用音讯队列的当前关联值覆盖msgid_ds的值。
   
IPC_SET:假如经过有丰裕的权杖,就把音信列队的最近关联值设置为msgid_ds结构中提交的值
    IPC_PAJEROMID:删除新闻队列  
buf是指向msgid_ds结构的指针,它指向音讯队列情势和做客权限的布局。msgid_ds结构至少包罗以下成员:
  [cpp] view plain copy    print?

  1. struct msgid_ds  
  2. {  
  3.     uid_t shm_perm.uid;  
  4.     uid_t shm_perm.gid;  
  5.     mode_t shm_perm.mode;  
  6. };  

成功时再次来到0,退步时再次来到-1.   ③ 、使用音信队列进行进度间通讯快马加鞭,介绍完新闻队列的定义和可选取的接口之后,大家来探望它是怎么让进程展开通讯的。由于能够让不相干的经过展开发银行通讯,所以大家在此地将会编写八个程序,msgreceive和msgsned来代表接到和发送音讯。依照平常的情状,大家允许五个程序都能够成立音讯,但唯有接收者在收受完最终八个音讯随后,它才把它删除。
  接收消息的程序源文件为msgreceive.c的源代码为:   [cpp] view
plain copy    print?

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/msg.h>  
  7.   
  8. struct msg_st  
  9. {  
  10.     long int msg_type;  
  11.     char text[BUFSIZ];  
  12. };  
  13.   
  14. int main()  
  15. {  
  16.     int running = 1;  
  17.     int msgid = -1;  
  18.     struct msg_st data;  
  19.     long int msgtype = 0; //注意1  
  20.   
  21.     //建立新闻队列  
  22.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  23.     if(msgid == -1)  
  24.     {  
  25.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  26.         exit(EXIT_FAILURE);  
  27.     }  
  28.     //从队列中收获音信,直到碰到end音讯甘休  
  29.     while(running)  
  30.     {  
  31.         if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
  32.         {  
  33.             fprintf(stderr, “msgrcv failed with errno: %d\n”, errno);  
  34.             exit(EXIT_FAILURE);  
  35.         }  
  36.         printf(“You wrote: %s\n”,data.text);  
  37.         //遇到end结束  
  38.         if(strncmp(data.text, “end”, 3) == 0)  
  39.             running = 0;  
  40.     }  
  41.     //删除消息队列  
  42.     if(msgctl(msgid, IPC_RMID, 0) == -1)  
  43.     {  
  44.         fprintf(stderr, “msgctl(IPC_RMID) failed\n”);  
  45.         exit(EXIT_FAILURE);  
  46.     }  
  47.     exit(EXIT_SUCCESS);  
  48. }  

发送音讯的主次的源文件msgsend.c的源代码为:   [cpp] view
plain copy    print?

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <sys/msg.h>  
  6. #include <errno.h>  
  7.   
  8. #define MAX_TEXT 512  
  9. struct msg_st  
  10. {  
  11.     long int msg_type;  
  12.     char text[MAX_TEXT];  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     int running = 1;  
  18.     struct msg_st data;  
  19.     char buffer[BUFSIZ];  
  20.     int msgid = -1;  
  21.   
  22.     //建立信息队列  
  23.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  24.     if(msgid == -1)  
  25.     {  
  26.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  27.         exit(EXIT_FAILURE);  
  28.     }  
  29.   
  30.     //向音信队列中写新闻,直到写入end  
  31.     while(running)  
  32.     {  
  33.         //输入数据  
  34.         printf(“Enter some text: “);  
  35.         fgets(buffer, BUFSIZ, stdin);  
  36.         data.msg_type = 1;    //注意2  
  37.         strcpy(data.text, buffer);  
  38.         //向队列发送数据  
  39.         if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
  40.         {  
  41.             fprintf(stderr, “msgsnd failed\n”);  
  42.             exit(EXIT_FAILURE);  
  43.         }  
  44.         //输入end停止输入  
  45.         if(strncmp(buffer, “end”, 3) == 0)  
  46.             running = 0;  
  47.         sleep(1);  
  48.     }  
  49.     exit(EXIT_SUCCESS);  
  50. }  

运转结果如下:  
澳门金沙国际 1
  ④ 、例子分析——新闻类型  

 

 

 

此处最主要说明一(Wissu)(Nutrilon)(Karicare)下消息类型是怎么一遍事,注意msgreceive.c文件main函数中定义的变量msgtype(注释为注意1),它看作msgrcv函数的选择消息项目参数的值,其值为0,表示收获队列中首先个可用的新闻。再来看看msgsend.c文件中while循环中的语句data.msg_type

1(注释为注意2),它用来设置发送的音信的音信连串,即其发送的音讯的类别为1。所以程序msgreceive能够吸收接纳到程序msgsend发送的音讯。
  借使把注意1,即msgreceive.c文件main函数中的语句由long int msgtype =
0;改变为long int msgtype =
2;会爆发如何情形,msgreceive将无法选用到程序msgsend发送的音信。因为在调用msgrcv函数时,若是msgtype(第多个参数)大于零,则将只收获具有同样音讯类型的率先个信息,修改后得到的音信类型为2,而msgsend发送的新闻类型为1,所以不可能被msgreceive程序接收。重新编写翻译msgreceive.c文件并重新实施,其结果如下:
 
澳门金沙国际 2
 
大家得以看出,msgreceive并从未接到到音信和输出,而且当msgsend输入end甘休后,msgreceive也绝非甘休,通过jobs命令大家得以见见它还在后台运维着。
  五 、消息队列与命名管道的可比  
信息队列跟命名管道有好多的相同之处,通过与命名管道一样,音讯队列实行通讯的长河能够是不相干的长河,同时它们都以透过发送和吸收的艺术来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在新闻队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对种种数据都有三个最大尺寸的界定。
 
与命名管道相比较,新闻队列的优势在于,① 、音讯队列也可以独自于发送和选取进程而存在,从而撤除了在同步命名管道的打开和关闭时大概发生的不方便。二 、同时通过发送消息还足避防止命名管道的协同和堵塞难点,不须要由进度自个儿来提供一块方法。三 、接收程序能够透过消息类型有选拔地接收数据,而不是像命名管道中那么,只可以暗中同意地接受。

上面包车型地铁话说哪些用不用音信队列来进展进度间的通讯,音讯队列与命名管道有许多相…

一 、什么是音讯队列

壹 、什么是音讯队列

一 、什么是音信队列

音讯队列提供了一种从一个进程向另八个进度发送一个数据块的格局。
 各类数据块都被认为包涵贰个品类,接收进度可以独立地接过含有分裂档次的数据结构。大家能够通过发送音信来防止命名管道的一块儿和鸿沟难点。但是音讯队列与命名管道一样,每一种数据块都有二个最大尺寸的限量。

音信队列提供了一种从三个经过向另1个经过发送2个数据块的办法。
 每一个数据块都被认为包涵三个连串,接收进度能够独自地吸收接纳含有分化档次的数据结构。我们得以透过发送新闻来防止命名管道的一路和封堵难题。然则新闻队列与命名管道一样,每一种数据块都有三个最大尺寸的限量。

信息队列提供了一种从多个进程向另一个进程发送1个数据块的法门。
 各类数据块都被认为包蕴一个档次,接收进度能够独自地收取含有不一致类别的数据结构。大家得以经过发送音讯来制止命名管道的联合和围堵难题。可是新闻队列与命名管道一样,各类数据块都有二个最大尺寸的限制。

 

 

 

Linux用宏MS核糖霉素AX和MS维生霉素NB来限制一条音讯的最大尺寸和一个队列的最大尺寸。

Linux用宏MS核糖霉素AX和MS阿奇霉素NB来限制一条新闻的最大尺寸和三个体系的最大尺寸。

Linux用宏MS罗红霉素AX和MS林大霉素NB来界定一条音讯的最大尺寸和二个队列的最大尺寸。

 

 

 

② 、在Linux中运用消息队列

贰 、在Linux中动用信息队列

② 、在Linux中应用新闻队列

Linux提供了一文山会海新闻队列的函数接口来让大家有益地动用它来兑现进程间的通讯。它的用法与别的四个System
V PIC机制,即信号量和共享内部存款和储蓄器相似。

Linux提供了一多如牛毛新闻队列的函数接口来让大家有利地行使它来落到实处进度间的通讯。它的用法与任何五个System
V PIC机制,即信号量和共享内存相似。

Linux提供了一多种新闻队列的函数接口来让大家有益地选拔它来达成进度间的通讯。它的用法与其余多个System
V PIC机制,即信号量和共享内部存款和储蓄器相似。

 

 

 

1、msgget函数

1、msgget函数

1、msgget函数

该函数用来创造和走访二个音讯队列。它的原型为:

该函数用来创立和走访多少个新闻队列。它的原型为:

该函数用来创立和做客一个音讯队列。它的原型为:

[cpp] view
plain copy

[cpp] view
plain copy

[cpp] view
plaincopyprint?

 

 

 

 print?

 print?

  1. int msgget(key_t, key, int msgflg);  
  1. int msgget(key_t, key, int msgflg);  
  1. int msgget(key_t, key, int msgflg);  

与其余的IPC机制一样,程序必须提供二个键来命名某些特定的新闻队列。msgflg是3个权力标志,表示音讯队列的拜会权限,它与公事的造访权限一样。msgflg能够与IPC_CREAT做或操作,表示当key所命名的音信队列不存在时创建七个信息队列,假若key所命名的新闻队列存在时,IPC_CREAT标志会被忽视,而只回去3个标识符。

与别的的IPC机制一样,程序必须提供五个键来定名有些特定的消息队列。msgflg是三个权力标志,表示音讯队列的访问权限,它与公事的访问权限一样。msgflg能够与IPC_CREAT做或操作,表示当key所命名的消息队列不设有时创制多个新闻队列,即便key所命名的音信队列存在时,IPC_CREAT标志会被忽略,而只回去几个标识符。

与别的的IPC机制一样,程序必须提供七个键来定名有个别特定的音信队列。msgflg是三个权力标志,表示新闻队列的拜访权限,它与公事的拜会权限一样。msgflg能够与IPC_CREAT做或操作,表示当key所命名的新闻队列不设有时创建3个音信队列,假设key所命名的音信队列存在时,IPC_CREAT标志会被忽略,而只回去贰个标识符。

 

 

 

它回到二个以key命名的信息队列的标识符(非零整数),退步时回来-1.

它回到2个以key命名的音信队列的标识符(非零整数),战败时重临-1.

它回到三个以key命名的消息队列的标识符(非零整数),战败时重临-1.

 

 

 

2、msgsnd函数

2、msgsnd函数

2、msgsnd函数

该函数用来把音信添加到信息队列中。它的原型为:

该函数用来把新闻添加到音信队列中。它的原型为:

该函数用来把消息添加到音信队列中。它的原型为:

[cpp] view
plaincopyprint?

[cpp] view
plain行使音信队列,linux进度新闻队列。 copy

[cpp] view
plain copy

 

 

 

  1. int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);  

 print?

 print?

msgid是由msgget函数重返的音讯队列标识符。

  1. int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);  
  1. int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);  

 

msgid是由msgget函数再次回到的音讯队列标识符。

msgid是由msgget函数再次来到的新闻队列标识符。

msg_ptr是多个针对性准备发送音讯的指针,不过音讯的数据结构却有一定的供给,指针msg_ptr所指向的音讯结构自然假设以一个长整型成员变量开首的结构体,接收函数将用这些成员来明显新闻的体系。所以消息结构要定义成这么:

 

 

 

msg_ptr是2个针对性准备发送消息的指针,不过音讯的数据结构却有必然的渴求,指针msg_ptr所指向的音信结构自然假诺以1个长整型成员变量开头的结构体,接收函数将用这几个成员来分明新闻的类型。所以新闻结构要定义成这样:

msg_ptr是多个对准准备发送信息的指针,不过音信的数据结构却有自然的渴求,指针msg_ptr所针对的音讯结构自然假若以1个长整型成员变量开始的结构体,接收函数将用那么些成员来规定音讯的品种。所以音讯结构要定义成这么:

[cpp] view
plaincopyprint?

 

 

 

[cpp] view
plain copy

[cpp] view
plain copy

  1. struct my_message{  
  2.     long int message_type;  
  3.     /* The data you wish to transfer*/  
  4. };  

 

 

msg_sz是msg_ptr指向的新闻的尺寸,注意是音信的尺寸,而不是整个结构体的长短,也正是说msg_sz是不包蕴长整型音信类型成员变量的长短。

 print?

 print?

 

  1. struct my_message{  
  2.     long int message_type;  
  3.     /* The data you wish to transfer*/  
  4. };  
  1. struct my_message{  
  2.     long int message_type;  
  3.     /* The data you wish to transfer*/  
  4. };  

msgflg用于控制当前音信队列满或队列音信到达系统范围的限制时就要发生的事体。

msg_sz是msg_ptr指向的音讯的尺寸,注意是消息的尺寸,而不是一切结构体的长短,约等于说msg_sz是不包蕴长整型新闻类型成员变量的长短。

msg_sz是msg_ptr指向的音信的长短,注意是音讯的长短,而不是百分之百结构体的长度,也正是说msg_sz是不包涵长整型音信类型成员变量的长度。

 

 

 

要是调用成功,音信数据的一分副本将被停放信息队列中,并再次来到0,退步时回来-1.

msgflg用于控制当前新闻队列满或队列消息到达系统范围的界定时就要发生的工作。

msgflg用于控制当前新闻队列满或队列音讯到达系统范围的范围时就要产生的事体。

 

 

 

3、msgrcv函数

一经调用成功,音信数据的一分副本将被放置新闻队列中,并再次回到0,失利时再次回到-1.

要是调用成功,音信数据的一分副本将被平放音讯队列中,并重临0,失败时回来-1.

该函数用来从四个消息队列获取音讯,它的原型为

 

 

[cpp] view
plaincopyprint?

3、msgrcv函数

3、msgrcv函数

 

该函数用来从四个音讯队列获取音讯,它的原型为

该函数用来从3个新闻队列获取音讯,它的原型为

  1. int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);  

[cpp] view
plain copy

[cpp] view
plain copy

msgid, msg_ptr, msg_st的功效也函数msgsnd函数的一致。

 

 

 

 print?

 print?

msgtype能够兑现一种不难的收取优先级。若是msgtype为0,就赢得队列中的第多少个音讯。假设它的值大于零,将取得具有相同音讯类型的率先个音讯。假设它小于零,就取得项目等于或低于msgtype的相对值的首先个消息。

  1. int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);  
  1. int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);  

 

msgid, msg_ptr, msg_st的成效也函数msgsnd函数的等同。

msgid, msg_ptr, msg_st的职能也函数msgsnd函数的平等。

msgflg用于控制当队列中从未对号入座品种的新闻能够收起时将时有爆发的事务。

 

 

 

msgtype能够兑现一种简易的收受优先级。假诺msgtype为0,就得到队列中的第二个新闻。倘诺它的值超出零,将获得具有同样新闻类型的第一个音信。要是它小于零,就收获项目等于或小于msgtype的相对值的率先个音讯。

msgtype能够兑现一种简易的收纳优先级。要是msgtype为0,就收获队列中的第二个音信。要是它的值大于零,将收获具有同等音信类型的首先个新闻。即使它小于零,就获得项目等于或小于msgtype的相对值的率先个新闻。

调用成功时,该函数返重播到接收缓存区中的字节数,音信被复制到由msg_ptr指向的用户分配的缓存区中,然后删除音讯队列中的对应信息。失败时重回-1.

 

 

 

msgflg用于控制当队列中绝非对应品种的新闻可以选择时将发生的作业。

msgflg用于控制当队列中并未相应类别的新闻能够收起时将产生的事体。

4、msgctl函数

 

 

该函数用来支配音讯队列,它与共享内部存款和储蓄器的shmctl函数相似,它的原型为:

调用成功时,该函数重回看到接收缓存区中的字节数,音讯被复制到由msg_ptr指向的用户分配的缓存区中,然后删除新闻队列中的对应新闻。失利时重临-1.

调用成功时,该函数重回看到接收缓存区中的字节数,新闻被复制到由msg_ptr指向的用户分配的缓存区中,然后删除信息队列中的对应新闻。退步时回来-1.

[cpp] view
plaincopyprint?

 

 

 

4、msgctl函数

4、msgctl函数

  1. int msgctl(int msgid, int command, struct msgid_ds *buf);  

该函数用来决定音信队列,它与共享内部存款和储蓄器的shmctl函数相似,它的原型为:

该函数用来控制音讯队列,它与共享内部存款和储蓄器的shmctl函数相似,它的原型为:

command是快要采纳的动作,它能够取二个值,

[cpp] view
plain copy

[cpp] view
plain copy

 
  IPC_STAT:把msgid_ds结构中的数据设置为音信队列的当下涉嫌值,即用信息队列的脚下关联值覆盖msgid_ds的值。

 

 

   
IPC_SET:即使经过有丰盛的权能,就把消息列队的当前关联值设置为msgid_ds结构中付出的值

 print?

 print?

    IPC_KugaMID:删除新闻队列

  1. int msgctl(int msgid, int command, struct msgid_ds *buf);  
  1. int msgctl(int msgid, int command, struct msgid_ds *buf);  

 

command是快要采取的动作,它能够取2个值,

command是即将利用的动作,它能够取二个值,

buf是指向msgid_ds结构的指针,它指向音讯队列格局和走访权限的结构。msgid_ds结构至少包括以下成员:

 
  IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当下涉嫌值,即用新闻队列的脚下关联值覆盖msgid_ds的值。

 
  IPC_STAT:把msgid_ds结构中的数据设置为音讯队列的眼下波及值,即用消息队列的当前关联值覆盖msgid_ds的值。

 

   
IPC_SET:假若经过有丰盛的权杖,就把新闻列队的近年来关联值设置为msgid_ds结构中提交的值

   
IPC_SET:假诺经过有丰盛的权杖,就把音讯列队的近年来关联值设置为msgid_ds结构中提交的值

[cpp] view
plaincopyprint?

    IPC_奔驰G级MID:删除音信队列

    IPC_奥迪Q3MID:删除音信队列

 

 

 

  1. struct msgid_ds  
  2. {  
  3.     uid_t shm_perm.uid;  
  4.     uid_t shm_perm.gid;  
  5.     mode_t shm_perm.mode;  
  6. };  

buf是指向msgid_ds结构的指针,它指向新闻队列情势和做客权限的构造。msgid_ds结构至少包涵以下成员:

buf是指向msgid_ds结构的指针,它指向音讯队列形式和做客权限的组织。msgid_ds结构至少包蕴以下成员:

打响时再次来到0,退步时回来-1.

 

 

 

[cpp] view
plain copy

[cpp] view
plain copy

③ 、使用新闻队列实行进度间通讯

 

 

快马加鞭,介绍完音信队列的概念和可采纳的接口之后,大家来探望它是怎么让进度展开通讯的。由于能够让不相干的经过展开发银行通讯,所以大家在此间将会编写五个程序,msgreceive和msgsned来表示接到和发送新闻。根据正常的动静,大家允许多个程序都得以成立新闻,但唯有接收者在接到完最终二个新闻随后,它才把它删除。

 print?

 print?

 

  1. struct msgid_ds  
  2. {  
  3.     uid_t shm_perm.uid;  
  4.     uid_t shm_perm.gid;  
  5.     mode_t shm_perm.mode;  
  6. };  
  1. struct msgid_ds  
  2. {  
  3.     uid_t shm_perm.uid;  
  4.     uid_t shm_perm.gid;  
  5.     mode_t shm_perm.mode;  
  6. };  

收起新闻的程序源文件为msgreceive.c的源代码为:

事业有成时再次来到0,失败时重回-1.

得逞时再次回到0,失利时重临-1.

 

 

 

[cpp] view
plaincopyprint?

叁 、使用消息队列进行进度间通讯

三 、使用音信队列实行进程间通讯

 

夜以继日,介绍完音讯队列的概念和可利用的接口之后,我们来探望它是怎么让过程展开通讯的。由于能够让不相干的长河展开发银行通信,所以大家在那里将会编写多个程序,msgreceive和msgsned来代表接到和发送新闻。依照健康的动静,大家允许四个程序都得以创设音讯,但唯有接收者在收取完最后三个新闻之后,它才把它删除。

囊虫映雪,介绍完音信队列的概念和可利用的接口之后,大家来探视它是怎么让进程展开通讯的。由于能够让不相干的长河展开发银行通讯,所以大家在那里将会编写五个程序,msgreceive和msgsned来表示接到和发送音信。依照健康的气象,我们允许几个程序都得以创造新闻,但唯有接收者在接收完最后1个音信随后,它才把它删除。

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/msg.h>  
  7.   
  8. struct msg_st  
  9. {  
  10.     long int msg_type;  
  11.     char text[BUFSIZ];  
  12. };  
  13.   
  14. int main()  
  15. {  
  16.     int running = 1;  
  17.     int msgid = -1;  
  18.     struct msg_st data;  
  19.     long int msgtype = 0; //注意1  
  20.   
  21.     //建立音信队列  
  22.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  23.     if(msgid == -1)  
  24.     {  
  25.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  26.         exit(EXIT_FAILURE);  
  27.     }  
  28.     //从队列中收获消息,直到遇见end音讯停止  
  29.     while(running)  
  30.     {  
  31.         if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
  32.         {  
  33.             fprintf(stderr, “msgrcv failed with errno: %d\n”, errno);  
  34.             exit(EXIT_FAILURE);  
  35.         }  
  36.         printf(“You wrote: %s\n”,data.text);  
  37.         //遇到end结束  
  38.         if(strncmp(data.text, “end”, 3) == 0)  
  39.             running = 0;  
  40.     }  
  41.     //删除音信队列  
  42.     if(msgctl(msgid, IPC_RMID, 0) == -1)  
  43.     {  
  44.         fprintf(stderr, “msgctl(IPC_RMID) failed\n”);  
  45.         exit(EXIT_FAILURE);  
  46.     }  
  47.     exit(EXIT_SUCCESS);  
  48. }  

 

 

发送信息的先后的源文件msgsend.c的源代码为:

收下新闻的程序源文件为msgreceive.c的源代码为:

接到音讯的程序源文件为msgreceive.c的源代码为:

 

 

 

[cpp] view
plaincopyprint?

[cpp] view
plain copy

[cpp] view
plain copy

 

 

 

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <sys/msg.h>  
  6. #include <errno.h>  
  7.   
  8. #define MAX_TEXT 512  
  9. struct msg_st  
  10. {  
  11.     long int msg_type;  
  12.     char text[MAX_TEXT];  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     int running = 1;  
  18.     struct msg_st data;  
  19.     char buffer[BUFSIZ];  
  20.     int msgid = -1;  
  21.   
  22.     //建立音信队列  
  23.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  24.     if(msgid == -1)  
  25.     {  
  26.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  27.         exit(EXIT_FAILURE);  
  28.     }  
  29.   
  30.     //向音信队列中写音信,直到写入end  
  31.     while(running)  
  32.     {  
  33.         //输入数据  
  34.         printf(“Enter some text: “);  
  35.         fgets(buffer, BUFSIZ, stdin);  
  36.         data.msg_type = 1;    //注意2  
  37.         strcpy(data.text, buffer);  
  38.         //向队列发送数据  
  39.         if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
  40.         {  
  41.             fprintf(stderr, “msgsnd failed\n”);  
  42.             exit(EXIT_FAILURE);  
  43.         }  
  44.         //输入end截至输入  
  45.         if(strncmp(buffer, “end”, 3) == 0)  
  46.             running = 0;  
  47.         sleep(1);  
  48.     }  
  49.     exit(EXIT_SUCCESS);  
  50. }  

 print?

 print?

运转结果如下:

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/msg.h>  
  7.   
  8. struct msg_st  
  9. {  
  10.     long int msg_type;  
  11.     char text[BUFSIZ];  
  12. };  
  13.   
  14. int main()  
  15. {  
  16.     int running = 1;  
  17.     int msgid = -1;  
  18.     struct msg_st data;  
  19.     long int msgtype = 0; //注意1  
  20.   
  21.     //建立新闻队列  
  22.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  23.     if(msgid == -1)  
  24.     {  
  25.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  26.         exit(EXIT_FAILURE);  
  27.     }  
  28.     //从队列中收获消息,直到碰着end音信截至  
  29.     while(running)  
  30.     {  
  31.         if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
  32.         {  
  33.             fprintf(stderr, “msgrcv failed with errno: %d\n”, errno);  
  34.             exit(EXIT_FAILURE);  
  35.         }  
  36.         printf(“You wrote: %s\n”,data.text);  
  37.         //遇到end结束  
  38.         if(strncmp(data.text, “end”, 3) == 0)  
  39.             running = 0;  
  40.     }  
  41.     //删除音讯队列  
  42.     if(msgctl(msgid, IPC_RMID, 0) == -1)  
  43.     {  
  44.         fprintf(stderr, “msgctl(IPC_RMID) failed\n”);  
  45.         exit(EXIT_FAILURE);  
  46.     }  
  47. 澳门金沙国际 ,    exit(EXIT_SUCCESS);  
  48. }  
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/msg.h>  
  7.   
  8. struct msg_st  
  9. {  
  10.     long int msg_type;  
  11.     char text[BUFSIZ];  
  12. };  
  13.   
  14. int main()  
  15. {  
  16.     int running = 1;  
  17.     int msgid = -1;  
  18.     struct msg_st data;  
  19.     long int msgtype = 0; //注意1  
  20.   
  21.     //建立音信队列  
  22.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  23.     if(msgid == -1)  
  24.     {  
  25.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  26.         exit(EXIT_FAILURE);  
  27.     }  
  28.     //从队列中收获音信,直到遇见end音讯截止  
  29.     while(running)  
  30.     {  
  31.         if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
  32.         {  
  33.             fprintf(stderr, “msgrcv failed with errno: %d\n”, errno);  
  34.             exit(EXIT_FAILURE);  
  35.         }  
  36.         printf(“You wrote: %s\n”,data.text);  
  37.         //遇到end结束  
  38.         if(strncmp(data.text, “end”, 3) == 0)  
  39.             running = 0;  
  40.     }  
  41.     //删除消息队列  
  42.     if(msgctl(msgid, IPC_RMID, 0) == -1)  
  43.     {  
  44.         fprintf(stderr, “msgctl(IPC_RMID) failed\n”);  
  45.         exit(EXIT_FAILURE);  
  46.     }  
  47.     exit(EXIT_SUCCESS);  
  48. }  

澳门金沙国际 3

发送音讯的顺序的源文件msgsend.c的源代码为:

发送消息的主次的源文件msgsend.c的源代码为:

 

 

 

澳门金沙国际 4

[cpp] view
plain copy

[cpp] view
plain copy

 

 

 

肆 、例子分析——新闻类型

 print?

 print?

 

  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <sys/msg.h>  
  6. #include <errno.h>  
  7.   
  8. #define MAX_TEXT 512  
  9. struct msg_st  
  10. {  
  11.     long int msg_type;  
  12.     char text[MAX_TEXT];  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     int running = 1;  
  18.     struct msg_st data;  
  19.     char buffer[BUFSIZ];  
  20.     int msgid = -1;  
  21.   
  22.     //建立信息队列  
  23.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  24.     if(msgid == -1)  
  25.     {  
  26.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  27.         exit(EXIT_FAILURE);  
  28.     }  
  29.   
  30.     //向音信队列中写信息,直到写入end  
  31.     while(running)  
  32.     {  
  33.         //输入数据  
  34.         printf(“Enter some text: “);  
  35.         fgets(buffer, BUFSIZ, stdin);  
  36.         data.msg_type = 1;    //注意2  
  37.         strcpy(data.text, buffer);  
  38.         //向队列发送数据  
  39.         if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
  40.         {  
  41.             fprintf(stderr, “msgsnd failed\n”);  
  42.             exit(EXIT_FAILURE);  
  43.         }  
  44.         //输入end停止输入  
  45.         if(strncmp(buffer, “end”, 3) == 0)  
  46.             running = 0;  
  47.         sleep(1);  
  48.     }  
  49.     exit(EXIT_SUCCESS);  
  50. }  
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <sys/msg.h>  
  6. #include <errno.h>  
  7.   
  8. #define MAX_TEXT 512  
  9. struct msg_st  
  10. {  
  11.     long int msg_type;  
  12.     char text[MAX_TEXT];  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     int running = 1;  
  18.     struct msg_st data;  
  19.     char buffer[BUFSIZ];  
  20.     int msgid = -1;  
  21.   
  22.     //建立音信队列  
  23.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  24.     if(msgid == -1)  
  25.     {  
  26.         fprintf(stderr, “msgget failed with error: %d\n”, errno);  
  27.         exit(EXIT_FAILURE);  
  28.     }  
  29.   
  30.     //向新闻队列中写音信,直到写入end  
  31.     while(running)  
  32.     {  
  33.         //输入数据  
  34.         printf(“Enter some text: “);  
  35.         fgets(buffer, BUFSIZ, stdin);  
  36.         data.msg_type = 1;    //注意2  
  37.         strcpy(data.text, buffer);  
  38.         //向队列发送数据  
  39.         if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
  40.         {  
  41.             fprintf(stderr, “msgsnd failed\n”);  
  42.             exit(EXIT_FAILURE);  
  43.         }  
  44.         //输入end截至输入  
  45.         if(strncmp(buffer, “end”, 3) == 0)  
  46.             running = 0;  
  47.         sleep(1);  
  48.     }  
  49.     exit(EXIT_SUCCESS);  
  50. }  

那边境海关键说圣元(Synutra)下音讯类型是怎么三遍事,注意msgreceive.c文件main函数中定义的变量msgtype(注释为注意1),它当做msgrcv函数的收取音讯项目参数的值,其值为0,表示收获队列中第二个可用的新闻。再来看看msgsend.c文件中while循环中的语句data.msg_type

1(注释为注意2),它用来安装发送的音讯的新闻体系,即其发送的音信的系列为1。所以程序msgreceive能够吸收到程序msgsend发送的新闻。

 

假若把注意1,即msgreceive.c文件main函数中的语句由long int msgtype =
0;改变为long int msgtype =
2;会发出什么样意况,msgreceive将不能够接收到程序msgsend发送的音信。因为在调用msgrcv函数时,假如msgtype(第两个参数)大于零,则将只得到具有同样音信类型的第二个音讯,修改后拿走的信息类型为2,而msgsend发送的音讯类型为1,所以不可能被msgreceive程序接收。重新编写翻译msgreceive.c文件并再一次实施,其结果如下:

 

澳门金沙国际 5

澳门金沙国际 6

 

我们能够看看,msgreceive并从未接收到信息和出口,而且当msgsend输入end甘休后,msgreceive也从未实现,通过jobs命令我们得以见到它还在后台运营着。

 

⑤ 、音讯队列与命名管道的相比

 

音讯队列跟命名管道有广大的相同之处,通过与命名管道一样,消息队列举办通讯的历程能够是不相干的历程,同时它们都以透过发送和吸收的章程来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在音信队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对各个数据都有2个最大尺寸的范围。

 

与命名管道比较,新闻队列的优势在于,① 、新闻队列也得以单独于发送和收受进程而留存,从而扫除了在同步命名管道的开辟和倒闭时只怕发生的孤苦。② 、同时经过发送信息还足以免止命名管道的联合和围堵难点,不须求由进度自个儿来提供一块方法。③ 、接收程序能够通过信息类型有选取地接收数据,而不是像命名管道中那么,只可以默许地选取。

运行结果如下:

运作结果如下:

 

 

澳门金沙国际 7

澳门金沙国际 8

 

 

四 、例子分析——新闻类型

肆 、例子分析——音信类型

 

 

此地最首要说美素佳儿下信息类型是怎么一次事,注意msgreceive.c文件main函数中定义的变量msgtype(注释为注意1),它看成msgrcv函数的收取音讯连串参数的值,其值为0,表示收获队列中第二个可用的新闻。再来看看msgsend.c文件中while循环中的语句data.msg_type

1(注释为注意2),它用来设置发送的新闻的音讯项目,即其发送的新闻的连串为1。所以程序msgreceive能够收到到程序msgsend发送的音信。

 

假诺把注意1,即msgreceive.c文件main函数中的语句由long int msgtype =
0;改变为long int msgtype =
2;会生出怎么样状态,msgreceive将无法收到到程序msgsend发送的新闻。因为在调用msgrcv函数时,假使msgtype(第多少个参数)大于零,则将只收获具有同样音信类型的第贰个新闻,修改后拿到的新闻类型为2,而msgsend发送的音信类型为1,所以不可能被msgreceive程序接收。重新编写翻译msgreceive.c文件同样重视复实施,其结果如下:

 

澳门金沙国际 9

 

大家能够见到,msgreceive并从未收取到音信和出口,而且当msgsend输入end甘休后,msgreceive也并未完毕,通过jobs命令我们得以看来它还在后台运转着。

 

伍 、音信队列与命名管道的比较

 

新闻队列跟命名管道有众多的相同之处,通过与命名管道一样,音讯队列举办通讯的历程能够是不相干的长河,同时它们都以透过发送和接到的不二法门来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在新闻队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对各种数据都有3个最大尺寸的范围。

 

与命名管道相比较,消息队列的优势在于,一 、新闻队列也得以单独于发送和接受进程而存在,从而解除了在一块命名管道的开辟和关闭时或者产生的劳碌。二 、同时通过发送新闻还足防止止命名管道的联合署名和堵塞难点,不须求由进程本身来提供一块方法。叁 、接收程序能够透过消息类型有选取地接收数据,而不是像命名管道中那么,只可以私下认可地采取。

那边根本说贝因美(Beingmate)(Nutrilon)下音信类型是怎么三遍事,注意msgreceive.c文件main函数中定义的变量msgtype(注释为注意1),它看做msgrcv函数的收纳新闻类别参数的值,其值为0,表示收获队列中率先个可用的音信。再来看看msgsend.c文件中while循环中的语句data.msg_type

1(注释为注意2),它用来设置发送的消息的音信连串,即其发送的新闻的品类为1。所以程序msgreceive能够吸收到程序msgsend发送的新闻。

 

万一把注意1,即msgreceive.c文件main函数中的语句由long int msgtype =
0;改变为long int msgtype =
2;会发出哪些情形,msgreceive将不可能接收到程序msgsend发送的音讯。因为在调用msgrcv函数时,假若msgtype(第多少个参数)大于零,则将只获得具有相同音讯类型的首先个音信,修改后收获的新闻类型为2,而msgsend发送的消息类型为1,所以无法被msgreceive程序接收。重新编写翻译msgreceive.c文件并再一次实施,其结果如下:

 

澳门金沙国际 10

 

我们得以见见,msgreceive并不曾接受到新闻和输出,而且当msgsend输入end结束后,msgreceive也从不实现,通过jobs命令我们得以看出它还在后台运转着。

 

五 、音讯队列与命名管道的可比

 

新闻队列跟命名管道有好多的相同之处,通过与命名管道一样,音讯队列进行通讯的历程能够是不相干的历程,同时它们都是经过发送和收取的章程来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在新闻队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对各种数据都有一个最大尺寸的范围。

 

与命名管道比较,音讯队列的优势在于,① 、消息队列也能够独自于发送和吸纳进程而留存,从而扫除了在一道命名管道的开拓和关闭时或者产生的紧Baba。二 、同时通过发送信息还能防止命名管道的2头和鸿沟难题,不须求由进度自个儿来提供联合方法。叁 、接收程序能够因此新闻类型有选取地接收数据,而不是像命名管道中那样,只好暗中同意地吸收。

相关文章