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 failed\n");
return 1;
}
/** 创建信号量*/
nSemid = semget(keyVal,1,IPC_CREAT);
if(-1 == nSemid)
{
printf("Create semget is failed\n");
return 1;
}
/** 设置信号量 */
if(-1 == semctl(nSemid,0,SETVAL,1))
{
printf("Set signal is failed\n");
return 0;
}
/**step3 申请共享内存指针 */
pchShm = (char*)shmat(nShmid,0,0);
if(NULL == pchShm)
{
printf("get share pointer failed\n");
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 failed\n");
return 1;
}
/**step3 申请共享内存指针 */
pchShm = (char*)shmat(nShmid,0,0);
if(NULL == pchShm)
{
printf("get share pointer failed\n");
return 1;
}
/** 创建信号量*/
nSemid = semget(keyVal,1,IPC_CREAT);
if(-1 == nSemid)
{
printf("Create semget is failed\n");
return 1;
}
/** 因为在写的文件里面已经设置过信号量了,在这里不能再设置*/
/* 判断信号量是否存在 */
semop(nSemid,&sem1_lock,1);
/** step4 对该共享指针进行操作 */
printf("%s\n",pchShm);
/* step5 释放该共享地址 */
shmdt(pchShm);
/* 信号量解锁 */
semop(nSemid,&sem1_unlock,1);
/** 删除该块共享内存 */
//shmctl(nShmid,IPC_RMID,NULL);
return 0;
}