当前位置: 首页 > 面试题库 >

在futex之前,如何在Linux中停放和唤醒线程/进程?

姜永贞
2023-03-14
问题内容

futex在Linux中存在系统调用之前,线程库使用了哪些底层系统调用,例如pthreads阻塞/hibernate了线程并随后从用户区唤醒了这些线程?

例如,如果某个线程尝试获取互斥量,则userland实现将阻塞该线程(可能在较短的旋转间隔之后),但是我找不到用于此目的的syscall(除了futex相对较新的创建之外)
)。


问题答案:

futex的和当前实现并行线程的Linux之前,NPTL(需要内核2.6和更高版本),此外,还有两个线程库与POSIX线程API的Linux:
Linux线程这和NGPT(基于对牛羚第P。LinuxThreads中是唯一的广泛应用libpthread已有多年历史了(它仍然可以在某些陌生且未维护的micro-
libc中使用,以在2.4上运行;其他micro-
libc变体可能在futex + clone
之上具有内置的类似pthread API
的内置实现。)Gnu
Pth是不是线程库,它是具有用户级“线程”切换的单进程线程。

你应该知道,有几个线程模型,当我们检查不内核知道的一些或所有用户线程(多少CPU内核可以增加线程程序中使用的;什么是具有线程/多少线程的成本可能会开始)。模型被命名为M:N,其中M是用户空间线程号,N是可由OS内核计划的线程号:

  • “ 1:1”“内核级线程”-OS内核可以调度每个用户空间线程。这是在Linuxthreads,NPTL和许多现代OS中实现的。
  • “ N:1”“用户级线程”-用户空间线程是由用户空间规划的,它们对于内核都是不可见的,它仅调度一个进程(并且可能仅使用1个CPU内核)。Gnu Pth(GNU可移植线程)就是它的示例,并且某些计算机体系结构还有许多其他实现。
  • “ M:N”“混合线程”-OS内核有一些可见且可调度的实体,但是其中可能有更多的用户空间线程。有时用户空间线程将在内核可见线程之间迁移。

在1:1模型中,Unix中有许多经典的睡眠机制/
API,例如选择/轮询和信号以及IPC
API的其他变体。我记得,Linuxthreads为每个线程(具有完全共享的内存)使用单独的进程,并且有特殊的管理器“线程”(进程)来模拟某些POSIX线程功能。Wikipedia表示SIGUSR1
/
SIGUSR2在Linuxthreads中用于线程之间的一些内部通信,IBM则说
“原语的同步是通过信号实现的。例如,线程阻塞直到被信号唤醒为止。”
另请检查项目常见问题解答http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html#H.4
“有了LinuxThreads,我不能再在程序中使用信号SIGUSR1和SIGUSR2!为什么?”

LinuxThreads的内部操作需要两个信号。 一种用于挂起和重新启动在互斥,条件或信号量操作中阻塞的线程。 另一个用于线程取消。
在``旧’‘内核(2.0和2.1早期的内核)上,只有32个可用信号,内核保留所有信号,但只有两个:SIGUSR1和SIGUSR2。因此,LinuxThreads除了使用这两个信号外别无选择。

使用“ N:1”模型线程可以调用某些阻塞的系统调用并阻塞所有内容(某些库可能会将某些阻塞的系统调用转换为异步,或使用某些SIGALRM或SIGVTALRM
magic);或者它可能调用某些(非常)特殊的内部线程功能,该功能将通过重写机器状态寄存器来进行用户空间线程切换(例如linux内核中的switch_to,保存IP
/ SP和其他注册表,恢复IP / SP和其他线程的注册表)
。因此,内核不会直接从userland唤醒任何用户线程,它只是调度整个进程。和用户空间调度程序实现线程同步逻辑(或仅sched_yield在没有工作线程时调用或选择)。

对于M:N模型,事情非常复杂…对NGPT不太了解…在POSIX线程和Linux内核中有关于NGPT的一小段
,Dave
McCracken,OLS2002,330,第5页

有一个正在开发的名为NGPT的新pthread库。该库基于GNU
Pth库,它是一个M:1库。NGPT通过使用多个Linux任务扩展了Pth,从而创建了M:N库。它试图保留Pth的pthread兼容性,同时还使用多个Linux任务进行并发,但是由于Linux线程模型的根本差异而使这项工作受阻。当前,NGPT库在阻塞系统调用周围使用非阻塞包装程序,以避免在内核中阻塞。

一些论文和文章:POSIX Threads和Linux Kernel,Dave
McCracken,OLS2002,330,LWN关于NPTL
0.1的文章

futex系统调用广泛用于所有同步原语和其他需要某种同步的地方。futex机制足够通用,可以非常轻松地支持标准POSIX同步机制。…
Futexes还允许实现进程间同步原语,这是旧版LinuxThreads实现中非常错过的​​功能(嗨,jbj!)。

NPTL设计pdf:

5.5同步原语同步原语(例如互斥锁,读写锁,条件变量,信号量和屏障)的实现需要某种形式的内核支持。繁忙等待不是一种选择,因为线程可能具有不同的优先级(除了浪费CPU周期之外)。相同的参数排除了计划收益率的排他性使用。
信号是旧实施的唯一可行解决方案。
线程将阻塞内核,直到被信号唤醒为止。该方法在速度和可靠性方面存在严重缺陷,这些缺陷是由虚假唤醒和应用中信号处理质量的下降引起的。幸运的是,内核中添加了一些新功能,以实现各种同步原语:futexes
[Futex]。基本原理很简单,但功能强大到足以适应各种用途。调用程序可以在内核中阻塞,也可以由于中断而显式唤醒,也可以在超时后唤醒。



 类似资料:
  • 我有2个工作线程和1个处理线程。 当处理线程正在尝试处理某些事情,而辅助线程正在执行它们的工作时,处理线程应该等待,并且在辅助线程中执行的所有作业完成时唤醒。 我怎样才能唤醒这根线?我将尝试演示我在这段伪代码中的意思 处理线程类似于 这样的事情可能发生吗?让线程等待到多个调用notifyAll()的源,而不是只等待一次。我希望我把这个问题弄清楚了。 多谢帮忙!

  • 本文向大家介绍HTML5如何唤醒APP?相关面试题,主要包含被问及HTML5如何唤醒APP?时的应答技巧和注意事项,需要的朋友参考一下 有以下几种方式 URL Scheme:最常见 Intent: // :Android Universal Link : iOS, 通过传统的 HTTP 链接即可打开 APP 唤醒途径 iframe的src a标签的src window.location 参考资料:

  • 我正在创建一个简单的web代理应用程序使用Java。基本上,main方法创建一个RequestReceiver对象,该对象具有侦听web浏览器http请求的ServerSocket。从ServerSocket.Accept()返回的套接字创建一个新的连接对象,并将其放入线程池中。

  • 我想做一个小练习来习惯等待/通知。我想做的是简单地启动一个线程,然后用等待让它进入睡眠状态,用通知唤醒它,多次。 我的代码是: 我希望这会是这样 相反,这样做: 所以。。。通知似乎没有唤醒打印机线程? 这不应该是一个死锁,因为通过等待,我释放了所有的锁,所以主服务器不应该有任何对打印机的锁,打印机应该能够唤醒并打印。 我做错了什么?

  • 下面我们来看看睡眠和醒来的基本模型。假设有两个系统调用作为睡眠和唤醒。呼叫睡眠的过程将被阻止,而调用的过程将被唤醒。 有一个叫做生产者消费者问题的流行例子,它是模拟睡眠和唤醒机制的最流行的问题。 睡眠和觉醒的概念非常简单。如果关键部分不是空的,那么该过程将进入休眠状态。它将被临界区内正在执行的其他进程唤醒,以便进程可以进入临界区。 在生产者消费者问题中,让我们说有两个过程,一个过程写某事,而另一个

  • 问题内容: 这是线程正在等待notify()或超时的情况。这里添加了while循环来处理虚假唤醒。 在这种情况下,如何区分虚假唤醒和超时?如果是虚假的唤醒,我需要回去等待。如果超时,我需要退出循环。 我可以轻松识别出notify()的情况,因为我将在notify()调用时将dosleep变量设置为false。 编辑:由于嵌入式项目的要求,我正在使用1.4 Java版本。我无法使用,因为它仅在1.5