Linux下IPC:信号量与共享内存详解

时间:2021-10-15 15:12:59
    蛋疼了很久,漏了一个括号,结果在shmat返回错误Identifier removed...废话不多说,最后解释。。    信号量,很多人把他和mutex进行类比,是的,可以简单认为mutex是信号量只在0-1变化的。不过二者还是有些差别的(现在我还没深入到。。),信号量表示资源数,如果信号量大于0,则表示他还有val个资源可以被获取,当val<=0时候表示没有信号量了,这里出现小于0是表示有多少进程在等待。   共享内存使得多个进程能够通过共享的内存区域进行通信。这个最大的好处就是在server/client上实现二者通信。   但是共享内存的过程有个同步问题随之而来,server什么时候去取得共享区域数据,什么时候不能取呢,我首先想到的就是用信号呗,确实,不过这里有个条件,client要知道server的pid,server也要知道client的pid,这个当然也是可以的。   还有一种方法就是采用信号量的方式(可以暂时理解成用锁的形式)来阻塞某一端,直至数据准备就绪再去取得数据。我这里用个网络上很流行的案例,server-client---------------------------------------设计目的:实现client向server传递数据,只有在client发送完毕后,server才取得数据,否则阻塞等待。设计思路:1、首先运行服务器,创建一个共享内存区域,存放数据;           2、同时创建一个semid,注意,信号量一般是多个(不像mutex就是一个0-1状态,这里semid表示信号量的id)int semid=semget(ket_t key,int nsems,int flag) key就是IPC的键了,nsems表示这个semid里有多少个信号量,flag表示权限,一般IPC_CREAT|IPC_EXCL|0666(注意下,IPC_EXCL这个表示如果key已经被绑定过则报错,这个在服务器里可以使用,但是客户机上就不要用IPC_EXCL当然IPC_CREAT也不用了),创建好semid。           3、这里细致说下sembuf和union semun                structsembuf{                     unsignedshort sem_num;//表示semid的第几个信号量0开始计数                     shortsem_op;//表示semop()函数后的操作,正:则向val加上sem_op;负:则val+(sem_op);当然也可以为0                     short sem_flg;//IPC_NOWAIT SEM_UNDO                }
                unionsemun{                      int val;//这个表示信号量的资源数 很关键的数,就是上面说的val                }
             4、后面的步骤就是围绕这些进行,看代码把--------------------server--------------------------------------------
  1 #include  2 #include  3 #include  4 #include  5 #include  6 #include  7 #include  8 #include  10 #define SEM_KEY 4001 11 #define SHM_KEY 5678 12 15  16  17 int semid,shmid; 18 int *shmptr; 19 struct sembuf sembuf1; 20 union semun { 21        int val; 22 }; 23  24 int main(void) 25 { 26        //create a shm  27        if((shmid =shmget(SHM_KEY,sizeof(int),IPC_CREAT|0666))<0){ 28              printf("create shm error\n"); 29              retur; 30        } 31        if((shmptr =shmat(shmid,NULL,0))==(int*)-1){ 32