3、For Example
下面这个例子,使用了【共享内存+信号量+消息队列】的组合来实现服务器进程与客户进程间的通信。
- 共享内存用来传递数据;
- 信号量用来同步;
- 消息队列用来 在客户端修改了共享内存后 通知服务器读取。
server.c
// 消息队列结构struct msg_form { long mtype; char mtext;};
// 联合体,用于semctl初始化union semun{ int val; /for SETVAL/ struct semid_ds buf; unsigned short *array;};
// 初始化信号量int init_sem(int sem_id, int value){ union semun tmp; tmp.val = value; if(semctl(sem_id, 0, SETVAL, tmp) == -1) { perror("Init Semaphore Error"); return -1; } return 0;}
// P操作:// 若信号量值为1,获取资源并将信号量值-1 // 若信号量值为0,进程挂起等待int sem_p(int sem_id){ struct sembuf sbuf; sbuf.sem_num = 0; /序号/ sbuf.sem_op = -1; /P操作/ sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id, &sbuf, 1) == -1) { perror("P operation Error"); return -1; } return 0;}
// V操作:// 释放资源并将信号量值+1// 如果有进程正在挂起等待,则唤醒它们int sem_v(int sem_id){ struct sembuf sbuf; sbuf.sem_num = 0; /序号/ sbuf.sem_op = 1; /V操作/ sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id, &sbuf, 1) == -1) { perror("V operation Error"); return -1; } return 0;}
// 删除信号量集int del_sem(int sem_id){ union semun tmp; if(semctl(sem_id, 0, IPC_RMID, tmp) == -1) { perror("Delete Semaphore Error"); return -1; } return 0;}
// 创建一个信号量集intcreat_sem(key_t key){ int sem_id; if((sem_id = semget(key, 1, IPC_CREAT|0666)) == -1) { perror("semget error"); exit(-1); } init_sem(sem_id, 1); /初值设为1资源未占用/ return sem_id;}
int main(){ key_t key; int shmid, semid, msqid; char shm; char data[] = "this is server"; struct shmid_ds buf1; /用于删除共享内存/ struct msqid_ds buf2; /用于删除消息队列/ struct msg_form msg; /消息队列用于通知对方更新了共享内存/
// 获取key值 if((key = ftok(".", 'z')) < 0) { perror("ftok error"); exit(1); }
// 创建共享内存 if((shmid = shmget(key, 1024, IPC_CREAT|0666)) == -1) { perror("Create Shared Memory Error"); exit(1); }
// 连接共享内存 shm = (char*)shmat(shmid, 0, 0); if((int)shm == -1) { perror("Attach Shared Memory Error"); exit(1); }
// 创建消息队列 if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) { perror("msgget error"); exit(1); }
// 创建信号量 semid = creat_sem(key); // 读数据 while(1) { msgrcv(msqid, &msg, 1, 888, 0); /读取类型为888的消息/ if(msg.mtext == 'q') /quit - 跳出循环/ break; if(msg.mtext == 'r') /read - 读共享内存/ { sem_p(semid); printf("%s\\n",shm); sem_v(semid); } }
// 断开连接 shmdt(shm);
/删除共享内存、消息队列、信号量/ shmctl(shmid, IPC_RMID, &buf1); msgctl(msqid, IPC_RMID, &buf2); del_sem(semid); return 0;}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
Linux
+关注
关注
88文章
11627浏览量
217888 -
IPC
+关注
关注
3文章
375浏览量
54542 -
进程间通信
+关注
关注
0文章
16浏览量
2575
发布评论请先 登录
相关推荐
热点推荐
Linux现有的所有进程间IPC方式
在开始回答前,先简单概括性地说说Linux现有的所有进程间IPC方式:1. **管道:**在创建时分配一个page大小的内存,缓存区大小比较有限;2. 消息队列:信息复制两次,额外的C
发表于 08-20 06:17
Linux进程间的五种通信方式介绍 3
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名
Linux进程间的五种通信方式介绍 4
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名
Linux进程间的五种通信方式介绍 6
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名

Linux进程间的五种通信方式介绍 5
评论