为什么 POSIX 将信号量标准化为系统调用,而将互斥量和条件变量留给 Pthread(用户级别)
Why POSIX standardize semaphore as system call but leave mutex and condition variable to Pthread (user level)
我想到了这个困扰我的奇怪问题。为什么 POSIX 将对信号量的支持标准化为系统调用,而将条件变量和互斥锁留给 pthread 库?
这里的职责划分是什么?为什么信号量在 Pthread 包中没有标准化?为什么POSIX标准化的同步系统调用是信号量而不是互斥量、条件变量?
不知道。猜测性能是不将互斥锁作为系统调用实现的关注点。 (原子硬件指令是非特权的,因此可以在用户级别实现它们。即使 Linux 提供 futex,它实际上是在尝试将自旋锁优化为两相锁,以实现睡眠锁)。而信号量的原因是信号量可以被不同的进程操纵,而不是互斥量只能由持有它的进程解锁的事实?信号量的 V 操作可以让等待它的进程畅通无阻。所以semaphore是由kernel保存的,semaphore的id就像文件描述符一样,是kernel赋予的能力,这使得它成为一个syscall而不是纯粹的用户级包。
但是条件变量呢?有什么理由在 Pthread 而不是系统调用级别中指定它?因为是无状态的,起源于monitor,是纯无状态的编程构造,所以可以用mutex来实现?
谢谢!
简答:信号量和 pthreads 有不同的历史。
是:可以在 pthreads 内容(通常)全部在当前进程内的进程之间或共享内存的进程之间使用信号量。
从性能的角度来看:快速戳一下(在我的 x86_64 上)告诉我 sem_wait()
和 sem_post()
使用简单的 lock cmpxchg
指令,做 syscall
只给suspend/wake-up一个线程。这与 pthread_mutex_t
本质上相同——当信号量用作互斥体时。
显然,信号量可以做互斥量和条件变量不能做的事情,并且您可以在进程中使用未命名的信号量 -- sem_init()
和 pshared=0
。
我猜 pthread 开发人员决定指定 pthread_sema_t
是不必要的重复。可悲的是,它确实让人怀疑(更一般的)信号量即使只在一个进程中使用也可能有性能问题:-(或者,事实上,有些人怀疑信号量和 pthread 的东西总是一起玩得很好:-(
我想到了这个困扰我的奇怪问题。为什么 POSIX 将对信号量的支持标准化为系统调用,而将条件变量和互斥锁留给 pthread 库?
这里的职责划分是什么?为什么信号量在 Pthread 包中没有标准化?为什么POSIX标准化的同步系统调用是信号量而不是互斥量、条件变量?
不知道。猜测性能是不将互斥锁作为系统调用实现的关注点。 (原子硬件指令是非特权的,因此可以在用户级别实现它们。即使 Linux 提供 futex,它实际上是在尝试将自旋锁优化为两相锁,以实现睡眠锁)。而信号量的原因是信号量可以被不同的进程操纵,而不是互斥量只能由持有它的进程解锁的事实?信号量的 V 操作可以让等待它的进程畅通无阻。所以semaphore是由kernel保存的,semaphore的id就像文件描述符一样,是kernel赋予的能力,这使得它成为一个syscall而不是纯粹的用户级包。
但是条件变量呢?有什么理由在 Pthread 而不是系统调用级别中指定它?因为是无状态的,起源于monitor,是纯无状态的编程构造,所以可以用mutex来实现?
谢谢!
简答:信号量和 pthreads 有不同的历史。
是:可以在 pthreads 内容(通常)全部在当前进程内的进程之间或共享内存的进程之间使用信号量。
从性能的角度来看:快速戳一下(在我的 x86_64 上)告诉我 sem_wait()
和 sem_post()
使用简单的 lock cmpxchg
指令,做 syscall
只给suspend/wake-up一个线程。这与 pthread_mutex_t
本质上相同——当信号量用作互斥体时。
显然,信号量可以做互斥量和条件变量不能做的事情,并且您可以在进程中使用未命名的信号量 -- sem_init()
和 pshared=0
。
我猜 pthread 开发人员决定指定 pthread_sema_t
是不必要的重复。可悲的是,它确实让人怀疑(更一般的)信号量即使只在一个进程中使用也可能有性能问题:-(或者,事实上,有些人怀疑信号量和 pthread 的东西总是一起玩得很好:-(