client.c
#include#include // shared memory#include // semaphore#include // message queue
// 消息队列结构struct msg_form {    long mtype;    char mtext;};
// 联合体,用于semctl初始化union semun{    int              val; /for setval/    struct semid_ds buf;    unsigned short  *array;};
// 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 main(){    key_t key;    int shmid, semid, msqid;    char shm;    struct msg_form msg;    int flag = 1; /while循环条件/
    // 获取key值    if((key = ftok(., 'z')) < 0)    {        perror(ftok error);        exit(1);    }
    // 获取共享内存    if((shmid = shmget(key, 1024, 0)) == -1)    {        perror(shmget error);        exit(1);    }
    // 连接共享内存    shm = (char*)shmat(shmid, 0, 0);    if((int)shm == -1)    {        perror(attach shared memory error);        exit(1);    }
    // 创建消息队列    if ((msqid = msgget(key, 0)) == -1)    {        perror(msgget error);        exit(1);    }
    // 获取信号量    if((semid = semget(key, 0, 0)) == -1)    {        perror(semget error);        exit(1);    }    // 写数据    printf(\\n);    printf(*                 ipc                 \\n);    printf(    input r to send data to server.  \\n);    printf(    input q to quit.                 \\n);    printf(\\n);    while(flag)    {        char c;        printf(please input command: );        scanf(%c, &c);        switch(c)        {            case 'r':                printf(data to send: );                sem_p(semid);  /访问资源/                scanf(%s, shm);                sem_v(semid);  /释放资源/                /清空标准输入缓冲区/                while((c=getchar())!='\\n' && c!=eof);                msg.mtype = 888;                  msg.mtext = 'r';  /发送消息通知服务器读数据/                msgsnd(msqid, &msg, sizeof(msg.mtext), 0);                break;            case 'q':                msg.mtype = 888;                msg.mtext = 'q';                msgsnd(msqid, &msg, sizeof(msg.mtext), 0);                flag = 0;                break;            default:                printf(wrong input!\\n);                /清空标准输入缓冲区*/                while((c=getchar())!='\\n' && c!=eof);        }    }
    // 断开连接    shmdt(shm);
    return 0;}注意:当scanf()输入字符或字符串时,缓冲区中遗留下了\\n,所以每次输入操作后都需要清空标准输入的缓冲区。但是由于 gcc 编译器不支持fflush(stdin)(它只是标准c的扩展),所以我们使用了替代方案:
while((c=getchar())!='\\n' && c!=eof);五种通讯方式总结1.管道:速度慢,容量有限,只有父子进程能通讯
2.fifo:任何进程间都能通讯,但速度慢
3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
4.信号量:不能传递复杂消息,只能用来同步
5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。
			
			
       	 	
    	360发飙!魅蓝5s+红米note4X,你们一起上!
         	 	
    	诺基亚贝尔:刷新光网络极限,赋能万物互联
         	 	
    	谷歌和亚马逊视频战争硝烟再起 YouTube再度封杀亚马逊硬件
         	 	
    	国产“核芯”技术受制于人 两大领域打响反击战
         	 	
    	三大运营商业绩负增长 争来争去最终都亏损
         	 	
    	Linux进程间的五种通信方式介绍 6
         	 	
    	能点烟的山寨手机强力现身
         	 	
    	One Plus 6T的渲染图近期有了新的消息
         	 	
    	人工智能对计算机系统及体系结构的挑战
         	 	
    	5G传输中面临的问题怎么解决?
         
       	 	
    	基于Modbus RTU协议的开关量控制采集的简单介绍
         	 	
    	【慕容话币】4.2 比特币众望所归的4200终于要到了吗?附行情策略
         	 	
    	中小企业发展的出路在何方
         	 	
    	把机器人操作系统(ROS)正式引入Win10!
         	 	
    	HoloLens、Magic Leap One、daystAR G1深度体验
         	 	
    	IMG.L宣布视频编码器IP中新增对VP8视频编解码技术的支持
         	 	
    	土壤含水量测定仪是什么,它的作用是什么
         	 	
    	sql语句中having的用法
         	 	
    	基于ZCU106实现PL PCIE Tandem PROM功能 从而满足100MS之内主板能识别PCIE接口
         	 	
    	晶体管开关速度有两种方法可以考虑一下