互斥锁:
保证某个进程只能启动一次之类的:
重点:
{sem_index, 0, IPC_NOWAIT}
期待信号量为0,如果不是,立即返回错误!
int sem_v_lock_mutex(int sem_id, int sem_index)
{
struct sembuf sops[2] = {{sem_index, 0, IPC_NOWAIT}, {sem_index, 1, SEM_UNDO}};
size_t nsops = 2;
assert(sem_id>=0);
printf("[%s:] sem_index:%d v + 1 \n\n", __func__, sem_index);
if (semop(sem_id, &sops[0], nsops ) == -1 ){
perror("v+1 error, haved v+1 [mutex locked]");
return -1;
}
return 0;
}
资源锁:
int sem_v(int sem_id, sem_index)
{
struct sembuf sops[2] = {{sem_index, 0, SEM_UNDO}, {sem_index, 1, SEM_UNDO}};
size_t nsops = 2;
assert(sem_id>=0);
if (semop(sem_id, &sops[0], nsops ) == -1 ){
perror("v+1 error, haved v+1 [mutex locked]");
return -1;
}
return 0;
}
int sem_p(int sem_id, sem_index)
{
struct sembuf sops[1] = {{sem_index, -1, SEM_UNDO}};
size_t nsops = 1;
assert(sem_id>=0);
if (semop(sem_id, &sops[0], nsops ) == -1 )
return -1;
return 0;
}
每次访问资源时,先sev_v 再 sev_p
这里的PV操作和信号量总觉得有点绕?
上面的实现个人觉得会比较简单:每次操作期待信号量值为0 -- 标识现在有0个进程正在使用某个资源,每个进程只有在无人访问的时候才可以去访问这个资源,这样就互斥访问了。
这里信号量的初始值为0.
如果信号量的初始值为1,则就可以完全对应使用pv操作了:
sem_p:
struct sembuf sops[1] = {{sem_index, -1, SEM_UNDO}, {sem_index, 0, SEM_UNDO}};
sem_v:
struct sembuf sops[1] = {{sem_index, 1, SEM_UNDO}};
这样调用的顺序就可以是:
sem_p
function()
sem_v
--EOF--
Leave a comment