使用开源的力量 - 只要看看源代码。
的内核空间旗语被定义为
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};
lock用于保护count和wait_list。
等待信号量的所有任务都驻留在wait_list中。当信号量被提升时,一个任务被唤醒。
用户空间信号量应该依赖于信号量相关的系统调用,Kernel提供。用户空间信号的定义如下:
/* One semaphore structure for each semaphore in the system. */
struct sem {
int semval; /* current value */
int sempid; /* pid of last operation */
spinlock_t lock; /* spinlock for fine-grained semtimedop */
struct list_head sem_pending; /* pending single-sop operations */
};
内核使用类似于内核空间信号量的用户空间信号量的定义。 sem_pending是一个等待进程的列表加上一些额外的信息。
我应该再次强调内核空间信号量和用户空间信号量都不使用自旋锁来等待锁定。 Spinlock仅包含在两种结构中,以保护结构成员免受并发访问。在结构被修改之后,释放螺旋锁并且任务停留在列表中直到唤醒。
此外,自旋锁不适合等待来自另一个线程的某个事件。在获取自旋锁之前,内核禁用抢占。所以,在这种情况下,在单处理器机器上,自旋锁永远不会被释放。
我还应该注意到,在代表用户空间服务时,用户空间信号在内核空间中执行。