Multithreading 是";“贝纳福利斯”;值得在现代操作系统上实施';s

Multithreading 是";“贝纳福利斯”;值得在现代操作系统上实施';s,multithreading,mutex,atomic,semaphore,Multithreading,Mutex,Atomic,Semaphore,在我作为BeOS程序员的日子里,我读过Benoit Schillings的文章,描述了如何创建“benaphore”:一种使用原子变量强制执行关键部分的方法,避免了在常见(无争用)情况下获取/释放互斥锁的需要 我认为这是相当聪明的,而且在任何支持原子递增/递减的平台上似乎都可以做同样的事情 另一方面,这看起来像是可以很容易地包含在标准互斥实现本身中的东西。。。在这种情况下,在我的程序中实现这种逻辑是多余的,不会带来任何好处 有人知道现代锁定API(例如pthread_mutex_lock()/p

在我作为BeOS程序员的日子里,我读过Benoit Schillings的文章,描述了如何创建“benaphore”:一种使用原子变量强制执行关键部分的方法,避免了在常见(无争用)情况下获取/释放互斥锁的需要

我认为这是相当聪明的,而且在任何支持原子递增/递减的平台上似乎都可以做同样的事情

另一方面,这看起来像是可以很容易地包含在标准互斥实现本身中的东西。。。在这种情况下,在我的程序中实现这种逻辑是多余的,不会带来任何好处


有人知道现代锁定API(例如pthread_mutex_lock()/pthread_mutex_unlock())是否在内部使用此技巧吗?如果没有,为什么不呢?

您的文章所描述的内容在今天很常用。它通常被称为“”,由一个互锁变量、一组标志和一个内部同步对象(互斥体,如果我没记错的话)组成。通常,在争用很少的场景中,关键部分完全以用户模式执行,而不涉及内核同步对象。这保证了快速执行。当争用较高时,内核对象用于等待,这将释放时间片以加快周转


一般来说,在这个时代实现同步原语是没有什么意义的。操作系统附带了各种各样的对象,它们在比单个程序员想象的范围更广的场景中进行了优化和测试。发明、实现和测试一个好的同步机制确实需要几年的时间。这并不是说尝试没有任何价值:)

你的文章所描述的内容在今天很常用。它通常被称为“”,由一个互锁变量、一组标志和一个内部同步对象(互斥体,如果我没记错的话)组成。通常,在争用很少的场景中,关键部分完全以用户模式执行,而不涉及内核同步对象。这保证了快速执行。当争用较高时,内核对象用于等待,这将释放时间片以加快周转

一般来说,在这个时代实现同步原语是没有什么意义的。操作系统附带了各种各样的对象,它们在比单个程序员想象的范围更广的场景中进行了优化和测试。发明、实现和测试一个好的同步机制确实需要几年的时间。这并不是说尝试没有任何价值:)

Java(及其兄弟)的工作原理类似,或者至少可以类似地实现。这些类型构成了Java库中几个并发原语的基础,如和

它的工作方式是使用原子整数来表示状态。锁可以将值0定义为已解锁,将值1定义为已锁定。任何希望获取锁的线程都试图通过原子比较和设置操作将锁状态从0更改为1;如果尝试失败,则当前状态不是0,这意味着锁属于其他线程

AbstractQueuedSynchronizer
还通过维护CLH队列(表示等待获取锁或通过条件接收通知的线程行的无锁链表)来帮助等待锁和条件通知。这样的通知会将等待条件的一个或所有线程移动到等待获取相关锁的线程的队列头

大多数这种机制都可以用表示状态的原子整数以及每个等待队列的两个原子指针来实现。线程将竞争检查和更改状态变量(例如,通过)的实际调度超出了这样一个库的范围,属于主机系统的调度程序。

Java(及其同级)的工作原理类似,或者至少可以类似地实现。这些类型构成了Java库中几个并发原语的基础,如和

它的工作方式是使用原子整数来表示状态。锁可以将值0定义为已解锁,将值1定义为已锁定。任何希望获取锁的线程都试图通过原子比较和设置操作将锁状态从0更改为1;如果尝试失败,则当前状态不是0,这意味着锁属于其他线程

AbstractQueuedSynchronizer
还通过维护CLH队列(表示等待获取锁或通过条件接收通知的线程行的无锁链表)来帮助等待锁和条件通知。这样的通知会将等待条件的一个或所有线程移动到等待获取相关锁的线程的队列头


大多数这种机制都可以用表示状态的原子整数以及每个等待队列的两个原子指针来实现。线程检查和更改状态变量(例如,通过)的实际调度超出了此类库的范围,属于主机系统的调度程序。

让我具体说明一下。在Linux上,现代(NPTL)线程库在内部依赖于futexes,这正是这个技巧,将未争用的情况保留在用户空间中,让内核处理争用的情况。引用手册页面“实现者应具备汇编知识,并已阅读futex用户空间库的源代码”。这件事真的很难,而且真的是不可原谅的错误。所以你不应该重新发明轮子,除非你有一个真正令人信服的理由。