Linux 进程间通信(一)

简介:

 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源。但是,进程不是孤立的,不同的进程之间需要信息的交换以及状态的传递,因此需要进程间数据传递、同步与异步的机制。

分类

  • 统一主机间进程通信
    • Unix进程间通信方式
      • 无名通道
      • 有名通道
      • 信号
    • System V进程间通信方式
      • 信号量
      • 消息队列
      • 共享内存
  • 不同主机间进程通信
      • RPC
      • Socket

消息队列IPC

简单介绍下,所有相关的API函数:

API函数 用途
msgget   创建一个新的消息队列       
  获取消息队列ID
msgsnd        向消息队列发送消息
msgrcv 从消息队列接受消息
msgctl 获得消息队列的信息
  设置消息队列的信息
  删除消息队列

函数原型如下:

复制代码
// 函数原型
#include <sys/msg.h>
 
int msgget( key_t key, int msgflag);
/*
key为消息队列的描述符
msgflag是一个设置选项,可以设置权限

返回值为消息队列ID
*/

int msgctl( int msgid, int cmd, struct msqid_ds *buf);
/*
msgid是msgget的返回值
cmd :IPC_STAT 获取消息队列当前的状态信息,保存到buf指向的空间
             IPC_SET  设置消息队列的属性
             IPC_RMID 从内核中删除msgid标识的消息队列
*/

int msgsnd( int msgid, struct msgbuf *msgp, size_t msgsz, int msgflag);
/*
msgid为消息队列ID
msgbuf 指向要发送的消息
msgsize 消息的大小
msgflag 操作标志位
*/

int msgrcv(int msgid, struct msgbuf *msgbuf, size_t msgsize, long int msgtype, int msgflag);
/*
msgtype用来指定要接收的消息,分三种情况:
等于 0 返回消息队列中的第一个消息
大于0  返回消息队列中类型为msgtype的第一个消息
小于0 返回消息队列中类型值小于等于msgtype绝对值的消息中类型值最小的第一条消息
*/
复制代码

例子:

复制代码
 1 #include <stdio.h>
 2 #include <sys/msg.h>
 3 #include <sys/types.h>
 4 #include <sys/ipc.h>
 5 
 6 int main()
 7 {
 8     int msgid;
 9     
10     //通过这样可以避免标识符的重复
11     //key_t myKey;
12     //myKey = ftok("/home/queues/myqueue", 0);
13 
14     msgid = msgget( 0x111, IPC_CREAT|0666);
15     if(msgid >= 0)
16         printf("Created a Msg Queue %d\n", msgid);
17         
18     return 0;
19 }
20 
21 创建消息队列
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/msg.h>
 3 #include <sys/types.h>
 4 
 5 int main(int argc, char **argv)
 6 {
 7     int msgid, ret;
 8     struct msqid_ds buf;
 9     
10     //获取消息队列
11     msgid = msgget(0x111, 0);
12     
13     if(msgid >= 0){
14         ret = msgctl(msgid, IPC_STAT, &buf);
15         buf.msg_qbytes = 4096;
16         
17         ret = msgctl(msgid, IPC_SET, &buf);
18         
19         if(ret == 0){
20             printf("change queue size success");
21         }
22     }
23     
24     return 0;
25 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/msg.h>
 3 #include <sys/types.h>
 4 #include <string.h>
 5 
 6 typedef struct{
 7     long type;
 8     float fval;
 9     unsigned int unival;
10     char message[1024];
11 }myType;
12 
13 int main()
14 {
15     myType msg;
16     int qid,ret;
17     
18     qid = msgget(0x111, 0);
19     if(qid > 0){
20         msg.type = 1L;
21         msg.fval = 123.456;
22         msg.unival = 256;
23         strcpy( msg.message, "this is a msg in queue\n");
24         
25         ret = msgsnd(qid, (struct msgbuf*)&msg, sizeof(myType), 0);
26         if(ret != -1)
27             printf("sent success!\n");
28     }
29     
30     return 0;
31 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/msg.h>
 3 #include <sys/types.h>
 4 #include <string.h>
 5 
 6 typedef struct{
 7     long type;
 8     float fval;
 9     unsigned int unival;
10     char message[1024];
11 }myType;
12 
13 int main()
14 {
15     myType msg;
16     int qid,ret;
17     
18     qid = msgget(0x111, 0);
19     if(qid >= 0){
20         
21         ret = msgsnd(qid, (struct msgbuf*)&msg, sizeof(myType), 0);
22         if(ret != -1)
23             printf("recv success!\n");
24             printf("type : %ld\n", msg.type);
25             printf("float value: %f\n", msg.fval);
26             printf("Unit value: %d\n", msg.unival);
27             printf("String value: %s\n", msg.message);
28     }
29     
30     return 0;
31 }
复制代码

共享内存

  使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间的一次复制,当另外一个进程要从消息队列中读取消息时,又要进行一次从内核空间向用户空间的一次复制。而共享内存的优点就是完全省去了这些复制操作。

  简单介绍下API函数:

API函数 用途                                                                                             
shmget             创建一个新的共享内存区段
  取得一个已经创建的共享内存区段的描述符
shmctl 取得一个共享内存区段的信息
  为一个共享内存区段设置特定的信息
  删除一个共享内存区段
shmat 挂接一个共享内存区段
shmdt 与一个共享内存区段分离

   函数原型如下:

复制代码
//函数原型
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>

int shmget( key_t key, size_t size, int shmflag );
/*
key为描述符
size为共享内存区段的大小
shmflag为指令和权限设置
*/

int shmctl( int shmid, int cmd, struct shmid_ds *buf );
/*
shmid指共享内存ID
cmd为指令
*/

void *shmat( int shmid, const void *shmaddr, int shmflag);
/*
shmaddr指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
shmflg SHM_RDONLY:为只读模式,其他为读写模式
*/

int shmdt( const void *shmaddr );
复制代码

例子:

复制代码
 1 #include <stdio.h>
 2 #include <sys/ipc.h>
 3 #include <sys/shm.h>
 4 
 5 int main()
 6 {
 7     int shmid;
 8     
 9     shmid = shmget( 0x123, 4096, IPC_CREAT|0666);
10     if(shmid >= 0)
11         printf("Created a shared memory %d\n", shmid);
12         
13     return 0;
14 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/shm.h>
 3 #include <errno.h>
 4 #include <sys/ipc.h>
 5 #include <sys/types.h>
 6 
 7 int main(int argc, char **argv)
 8 {
 9     int shmid, ret;
10     struct shmid_ds shmds;
11     
12     //获取共享内存
13     shmid = shmget(0x123, 0, 0);
14     
15     if(shmid >= 0){
16         ret = shmctl(shmid, IPC_STAT, &shmds);
17         if(ret == 0){
18             printf("shared memory size : %d/n", shmds.shm_segsz);
19             printf("attaches number: %d/n", (int)shmds.shm_nattch);
20         }else
21             printf("shmctl error!\n");
22     }else
23         printf("shared memory not found!\n");
24     
25     return 0;
26 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/shm.h>
 3 #include <errno.h>
 4 #include <sys/ipc.h>
 5 #include <sys/types.h>
 6 #include <string.h>
 7 
 8 int main(int argc, char **argv)
 9 {
10     int shmid, ret;
11     void* mem;
12     
13     //获取共享内存
14     shmid = shmget(0x123, 0, 0);
15     
16     if(shmid >= 0){
17         
18         mem = shmat( shmid, (const void*)0, 0 );
19         
20         strcpy((char*)mem, "This is a shared memory\n");
21         
22         ret = shmdt(mem);
23         
24     }else
25         printf("shared memory not found!\n");
26     
27     return 0;
28 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/shm.h>
 3 #include <errno.h>
 4 #include <sys/ipc.h>
 5 #include <sys/types.h>
 6 #include <string.h>
 7 
 8 int main(int argc, char **argv)
 9 {
10     int shmid, ret;
11     void* mem;
12     
13     //获取共享内存
14     shmid = shmget(0x123, 0, 0);
15     
16     if(shmid >= 0){
17         
18         mem = shmat( shmid, (const void*)0, 0 );
19         
20         printf("%s", (char*)mem);
21         
22         ret = shmdt(mem);
23         
24     }else
25         printf("shared memory not found!\n");
26     
27     return 0;
28 }
复制代码
复制代码
 1 #include <stdio.h>
 2 #include <sys/shm.h>
 3 #include <errno.h>
 4 #include <sys/ipc.h>
 5 #include <sys/types.h>
 6 
 7 int main(int argc, char **argv)
 8 {
 9     int shmid, ret;
10     
11     //获取共享内存
12     shmid = shmget(0x123, 0, 0);
13     
14     if(shmid >= 0){
15         ret = shmctl(shmid, IPC_RMID, 0);
16         if(ret == 0){
17             printf("shared memory removed!");
18         }else
19             printf("shmctl error!\n");
20     }else
21         printf("shared memory not found!\n");
22     
23     return 0;
24 }
复制代码

 

参考

GNU/Linux环境编程

http://blog.sina.com.cn/s/blog_7f98bac10100s91d.html

http://www.cnblogs.com/joeblackzqq/archive/2011/05/31/2065161.html 

 

 

知识共享许可协议
Linux 进程间通信 由  cococo点点 创作,采用  知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:转载自: cococo点点  http://www.cnblogs.com/coder2012

知识共享许可协议
本文 由 cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:cococo点点 http://www.cnblogs.com/coder2012

相关文章
|
1天前
|
NoSQL Linux 程序员
【linux进程信号(一)】信号的概念以及产生信号的方式
【linux进程信号(一)】信号的概念以及产生信号的方式
|
1天前
|
Linux
【linux进程间通信(一)】匿名管道和命名管道
【linux进程间通信(一)】匿名管道和命名管道
|
1天前
|
Java Shell Linux
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
|
1天前
|
算法 Linux Shell
【linux进程(二)】如何创建子进程?--fork函数深度剖析
【linux进程(二)】如何创建子进程?--fork函数深度剖析
|
1天前
|
存储 Linux Shell
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
|
2天前
|
消息中间件 Unix Linux
Linux的学习之路:17、进程间通信(1)
Linux的学习之路:17、进程间通信(1)
17 1
|
3天前
|
存储 安全 Linux
Linux的学习之路:9、冯诺依曼与进程(1)
Linux的学习之路:9、冯诺依曼与进程(1)
18 0
|
8天前
|
算法 Linux 调度
深入理解Linux内核的进程调度机制
【4月更文挑战第17天】在多任务操作系统中,进程调度是核心功能之一,它决定了处理机资源的分配。本文旨在剖析Linux操作系统内核的进程调度机制,详细讨论其调度策略、调度算法及实现原理,并探讨了其对系统性能的影响。通过分析CFS(完全公平调度器)和实时调度策略,揭示了Linux如何在保证响应速度与公平性之间取得平衡。文章还将评估最新的调度技术趋势,如容器化和云计算环境下的调度优化。
|
9天前
|
监控 Linux
linux监控指定进程
请注意,以上步骤提供了一种基本的方式来监控指定进程。根据你的需求,你可以选择使用不同的工具和参数来获取更详细的进程信息。
14 0
|
10天前
|
消息中间件 监控 Linux
Linux进程和计划任务管理
通过这些命令和工具,你可以有效地管理Linux系统中的进程和计划任务,监控系统的运行状态并保持系统的稳定和可靠性。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
102 2