linux 信号量操作函数

down, up, sem_p, sem_v, sem_wait, sem_post. 有什么区别
undefined reference to `down' ,需要包含哪个头文件?

第1个回答  推荐于2017-10-03
semget()
可以使用系统调用semget()创建一个新的信号量集,或者存取一个已经存在的信号量集:
系统调用:semget();
原型:intsemget(key_t key,int nsems,int semflg);
返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1:errno=EACCESS(没有权限)
EEXIST(信号量集已经存在,无法创建)
EIDRM(信号量集已经删除)
ENOENT(信号量集不存在,同时没有使用IPC_CREAT)
ENOMEM(没有足够的内存创建新的信号量集)
ENOSPC(超出限制)
系统调用semget()的第一个参数是关键字值(一般是由系统调用ftok()返回的)。系统内核将此值和系统中存在的其他的信号量集的关键字值进行比 较。打开和存取操作与参数semflg中的内容相关。IPC_CREAT如果信号量集在系统内核中不存在,则创建信号量集。IPC_EXCL当和 IPC_CREAT一同使用时,如果信号量集已经存在,则调用失败。如果单独使用IPC_CREAT,则semget()要么返回新创建的信号量集的标识 符,要么返回系统中已经存在的同样的关键字值的信号量的标识符。如果IPC_EXCL和IPC_CREAT一同使用,则要么返回新创建的信号量集的标识 符,要么返回-1。IPC_EXCL单独使用没有意义。参数nsems指出了一个新的信号量集中应该创建的信号量的个数。信号量集中最多的信号量的个数是 在linux/sem.h中定义的:
#defineSEMMSL32/*<=512maxnumofsemaphoresperid*/
下面是一个打开和创建信号量集的程序:
intopen_semaphore_set(key_t keyval,int numsems)
{
intsid;
if(!numsems)
return(-1);
if((sid=semget(mykey,numsems,IPC_CREAT|0660))==-1)
{
return(-1);
}
return(sid);
}
};
==============================================================
semop()
系统调用:semop();
调用原型:int semop(int semid,struct sembuf*sops,unsign ednsops);
返回值:0,如果成功。-1,如果失败:errno=E2BIG(nsops大于最大的ops数目)
EACCESS(权限不够)
EAGAIN(使用了IPC_NOWAIT,但操作不能继续进行)
EFAULT(sops指向的地址无效)
EIDRM(信号量集已经删除)
EINTR(当睡眠时接收到其他信号)
EINVAL(信号量集不存在,或者semid无效)
ENOMEM(使用了SEM_UNDO,但无足够的内存创建所需的数据结构)
ERANGE(信号量值超出范围)
第一个参数是关键字值。第二个参数是指向将要操作的数组的指针。第三个参数是数组中的操作的个数。参数sops指向由sembuf组成的数组。此数组是在linux/sem.h中定义的:
/*semop systemcall takes an array of these*/
structsembuf{
ushortsem_num;/*semaphore index in array*/
shortsem_op;/*semaphore operation*/
shortsem_flg;/*operation flags*/
sem_num将要处理的信号量的个数。
sem_op要执行的操作。
sem_flg操作标志。
如果sem_op是负数,那么信号量将减去它的值。这和信号量控制的资源有关。如果没有使用IPC_NOWAIT,那么调用进程将进入睡眠状态,直到信号 量控制的资源可以使用为止。如果sem_op是正数,则信号量加上它的值。这也就是进程释放信号量控制的资源。最后,如果sem_op是0,那么调用进程 将调用sleep(),直到信号量的值为0。这在一个进程等待完全空闲的资源时使用。
第2个回答  推荐于2017-10-13
down和up函数在内核源代码的semaphore.h里。
你可以看一下/usr/src/内核的版本/include/linux里的源文件。
引入linux/semaphore.h,注意链接路径的环境变量要设对。

sem_p和sem_v没听说过,不过down和up分别对应的就是p和v,估计没什么区别,可能是新版本里的吧。

sem_wait和sem_post也是对应p和v,但它们不是linux内核库中的,是GNU C库里的,可以去/usr/include下看头文件。直接引入semaphore.h即可。

down和up操作的是linux内核里的信号量。
而sem_wait和sem_post应该遵循POSIX标准的,在编写多线程程序时,操作用户进程里的信号量,在其他操作系统中也有。追问

写一个程序,gcc时,编译器是如何知道该代码里的信号量是内核信号量还是用户层的信号量?
我是在这个情况下遇到这个问题的:
我写了一个小程序,在里面开辟了一段共享内存,开了两个线程,
一个写线程,一个读线程,
进行同步和互斥时,
sem_p和sem_v,sem_wait和sem_post,可以,
down和up却不可以,提示为定义。
愿听详解

追答

down和up是写驱动时用的,用户程序里是用不了。内核模块和用户程序完全不一样,用的是两套C库。

本回答被提问者采纳
相似回答