1、信号量使用流程
(1)获得keyVal值。keyVal=ftok(PATH_SHM,PRI_SHM_ID);
(2)创建信号量或打开信号量的键值nSemid=semget(keyVal,1,IPC_CREAT);
(3)设置信号量semctl(nSemid,0,SETVAL,1)
(4)判断现在该资源是否被加锁,如果加锁则阻塞,如果不枷锁,则该进程把这块资源加锁,现在由这个进程使用。在对资源使用之前要进行判断。struct sembuf sem1_lock = {0,-1,SEM_UNDO}; struct sembuf sem1_unlock = {0,1,SEM_UNDO}; semop(nSemid,&sem1_lock,1);
(5)使用结束之后,解锁struct sembuf sem1_lock = {0,-1,SEM_UNDO}; struct sembuf sem1_unlock = {0,1,SEM_UNDO}; semop(nSemid,&sem1_unlock,1);
(6)如果信号量不再使用之后,则删除semctl(nSemid , IPC_RMID, NULL);
2、使用信号量注意事项(一定要注意)
(1) 信号量和共享内存要一起用。在运行可执行文件的时候,要以管理员权限来运行。
(2)当需要对一个共享内存读写的时候,只需要在读的进程或写的进程,设置一次信号量就可以了。一定不能在A进程和B进程都设置,否则上次设置的就会失效。
3、Linux C代码实现。(对共享内存加锁)
共享内存写入端代码:#include #include #include #include #include #include #include #include #define PRI_SHM_ID 1000 #define PATH_SHM "/home/nii/" int main() { key_t keyVal = 0; int nShmid = 0; int nSemid = 0 ; int nIsSignalUsed = 0; char *pchShm = NULL; struct sembuf sem1_lock = {0,-1,SEM_UNDO}; struct sembuf sem1_unlock = {0,1,SEM_UNDO}; /* step 1 获得key值 */ keyVal = ftok(PATH_SHM,PRI_SHM_ID); /** step 2 申请共享内存 */ nShmid = shmget(keyVal,10,IPC_CREAT|0666); if(nShmid == -1) { printf("create share memory failedn"); return 1; } /** 创建信号量*/ nSemid = semget(keyVal,1,IPC_CREAT); if(-1 == nSemid) { printf("Create semget is failedn"); return 1; } /** 设置信号量 */ if(-1 == semctl(nSemid,0,SETVAL,1)) { printf("Set signal is failedn"); return 0; } /**step3 申请共享内存指针 */ pchShm = (char*)shmat(nShmid,0,0); if(NULL == pchShm) { printf("get share pointer failedn"); return 1; } semop(nSemid,&sem1_lock,1); /** step4 对该共享指针进行操作 */ strncpy(pchShm,"Hello",6); /* 为了测试,占用该块的共享内存,不释放 */ while(1); /* step5 释放该共享地址 */ shmdt(pchShm);/* step5 释放该共享地址 */ /* 解锁信号量 */ semop(nSemid,&sem1_unlock,1); /** 删除该块共享内存 */ // shmctl(nShmid,IPC_RMID,NULL); return 0; }
共享内存读取端代码:#include #include #include #include #include #include #include #define PRI_SHM_ID 1000 #define PATH_SHM "/home/nii/" int main() { key_t keyVal = 0; int nShmid = 0; char *pchShm = NULL; int nSemid = 0 ; int nIsSignalUsed = 0; struct sembuf sem1_lock = {0,-1,SEM_UNDO}; struct sembuf sem1_unlock = {0,1,SEM_UNDO}; /* step 1 获得key值 */ keyVal = ftok(PATH_SHM,PRI_SHM_ID); /** step 2 申请共享内存 */ nShmid = shmget(keyVal,10,IPC_CREAT|0666); if(nShmid == -1) { printf("create share memory failedn"); return 1; } /**step3 申请共享内存指针 */ pchShm = (char*)shmat(nShmid,0,0); if(NULL == pchShm) { printf("get share pointer failedn"); return 1; } /** 创建信号量*/ nSemid = semget(keyVal,1,IPC_CREAT); if(-1 == nSemid) { printf("Create semget is failedn"); return 1; } /** 因为在写的文件里面已经设置过信号量了,在这里不能再设置*/ /* 判断信号量是否存在 */ semop(nSemid,&sem1_lock,1); /** step4 对该共享指针进行操作 */ printf("%sn",pchShm); /* step5 释放该共享地址 */ shmdt(pchShm); /* 信号量解锁 */ semop(nSemid,&sem1_unlock,1); /** 删除该块共享内存 */ //shmctl(nShmid,IPC_RMID,NULL); return 0; }
有关信号量的知识,请看我的另外一篇博客。
http://blog.csdn.net/u010889616/article/details/48116505