Linux信号量:自旋锁或信号?

use*_*879 1 linux semaphore linux-kernel

当前信号量的实现如何工作?它使用自旋锁或信号吗?

如果使用信号,调度程序如何知道调用哪一个?

它在用户空间中如何工作?内核锁定建议使用自旋锁,但用户空间不会.那么信号量的用户空间和内核空间的实现是否也不同?

Ale*_*lko 5

使用开源的力量 - 只需查看源代码.

内核空间的信号被定义为

struct semaphore {
    raw_spinlock_t      lock;
    unsigned int        count;
    struct list_head    wait_list;
};
Run Code Online (Sandbox Code Playgroud)

lock用于保护countwait_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 */
};
Run Code Online (Sandbox Code Playgroud)

内核使用类似于内核空间信号量的用户空间信号量的定义.sem_pending是一个等待过程的列表加上一些额外的信息.

我应该再次强调,内核空间信号量和用户空间都不使用自旋锁等待锁定.两个结构中都包含Spinlock,仅用于保护结构成员免受并发访问.修改结构后,会释放自旋锁,任务将停留在列表中直到被唤醒.

此外,自旋锁不适合等待来自另一个线程的某些事件.在获取自旋锁之前,内核禁用抢占.因此,在这种情况下,在单处理器机器上,永远不会释放螺旋锁.

我还应该注意到,用户空间信号量在代表用户空间服务时,正在内核空间中执行.

PS内核空间信号量的源代码位于include/linux/semaphore.hkernel/semaphore.c中,用于ipc/sem.c中的用户空间信息.