博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux 进程间通信(一)
阅读量:5836 次
发布时间:2019-06-18

本文共 7038 字,大约阅读时间需要 23 分钟。

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

分类

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

消息队列IPC

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

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

函数原型如下:

// 函数原型#include 
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为消息队列IDmsgbuf 指向要发送的消息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 
2 #include
3 #include
4 #include
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 
2 #include
3 #include
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 
2 #include
3 #include
4 #include
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 
2 #include
3 #include
4 #include
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 
#include
#include
int shmget( key_t key, size_t size, int shmflag );/*key为描述符size为共享内存区段的大小shmflag为指令和权限设置*/int shmctl( int shmid, int cmd, struct shmid_ds *buf );/*shmid指共享内存IDcmd为指令*/void *shmat( int shmid, const void *shmaddr, int shmflag);/*shmaddr指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置shmflg SHM_RDONLY:为只读模式,其他为读写模式*/int shmdt( const void *shmaddr );

例子:

1 #include 
2 #include
3 #include
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 
2 #include
3 #include
4 #include
5 #include
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 }else21 printf("shmctl error!\n");22 }else23 printf("shared memory not found!\n");24 25 return 0;26 }
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
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 }else25 printf("shared memory not found!\n");26 27 return 0;28 }
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
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 }else25 printf("shared memory not found!\n");26 27 return 0;28 }
1 #include 
2 #include
3 #include
4 #include
5 #include
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 }else19 printf("shmctl error!\n");20 }else21 printf("shared memory not found!\n");22 23 return 0;24 }

 

参考

GNU/Linux环境编程

 

 

 

Linux 进程间通信 由   创作,采用  进行许可。欢迎转载,请注明出处:转载自:  

本文 由  创作,采用 进行许可。欢迎转载,请注明出处:
转载自: 

你可能感兴趣的文章
软件测试流程
查看>>
Uncaught TypeError: xxx.submit is not a function解决方案
查看>>
07.继承和聚合
查看>>
关于Cursor的moveToFirst和moveToNext的意义
查看>>
个人--工资划分5份
查看>>
虚拟化--006 vmware高级内存属性
查看>>
有关文件下载的文件名
查看>>
ubuntu jdk环境安装
查看>>
史上最详细的wamp配置虚拟域名步骤
查看>>
oracle 授权
查看>>
lv扩展磁盘空间
查看>>
线程与进程
查看>>
java8之stream流的基本操作
查看>>
Cap定理和Base理论
查看>>
网站建站攻略(windows系统下)
查看>>
全球用户信息泄露事故频发 企业须加强防范
查看>>
二维数组计算协方差java
查看>>
Spring Boot 动手写一个 Start
查看>>
MongoDB数据库安装及配置环境(windows10系统)
查看>>
浅谈OceanBase的多线程并发日志回放
查看>>