【问题标题】:What happens to other thread when one thread get blocked?当一个线程被阻塞时,其他线程会发生什么?
【发布时间】:2010-01-27 22:04:57
【问题描述】:

在 Linux 中,如果创建了两个线程并且它们都在运行,当其中一个调用 recv() 或任何在没有数据可用时阻塞的 IO 系统调用时,整个进程会发生什么?

其他线程也会阻塞吗?我想这取决于线程是如何实现的。如果线程库在用户空间并且内核完全不知道进程中的线程,那么进程是调度实体,因此两个线程都被阻塞了。

此外,如果其他线程没有因此而阻塞,那么它是否可以通过同一个套接字将send() 数据阻塞recv 线程?双面打印?

有什么想法吗?

【问题讨论】:

    标签: c multithreading


    【解决方案1】:

    您完全正确,阻塞行为将取决于线程是在内核空间还是在用户空间中实现的。如果线程纯粹在用户空间中实现(即内核完全不参与线程),那么任何进入内核的阻塞入口点都需要用一些非阻塞变体包装,这些变体可以模拟阻塞语义到它的调用“线程”(例如使用 AIO 发送/接收数据而不是阻塞,完成回调使线程再次可运行)。

    在 Linux(以及我能想到的所有其他现存主要操作系统)中,线程是在内核级别或类似级别实现的,对内核的阻塞调用不会导致所有其他线程块。

    是的,您可以将send() 连接到另一个线程在recv() 上被阻塞的套接字。

    【讨论】:

    • 还有一个问题,如果在线程调用recv()之前有数据到达socket,线程真的会得到这些数据吗?
    • 是的。这确实是它可以在非阻塞数据报套接字上工作的唯一方法。一些小笔记,我打算提供帮助 - 一个,你可以很容易地尝试这种事情。编写一个小程序,它将accept 连接,然后sleep 一会儿,然后在新连接上调用recv。使用nc (netcat) 或其他东西来创建与服务器的连接,并立即向其写入一些数据。您会看到服务器收到的数据与您发送的数据相同。第二个注意事项 - 这实际上是关于什么通常是一个问题的论坛的第三个不同的问题......
    【解决方案2】:

    在一个线程中阻塞调用不应影响其他线程。

    如果阻塞线程在进入阻塞调用之前锁定了一个互斥体,并且第二个线程尝试锁定同一个互斥体,那么第二个线程将需要等待阻塞调用完成并等待第一个线程释放锁。

    【讨论】:

    • 谢谢,那么它就进入第二个问题:当 recv() 阻塞另一个时,其他非阻塞线程能否通过同一个套接字发送()数据?假设 UDP。
    【解决方案3】:

    完全可以在用户空间中实现线程,这样一个线程可以继续,而另一个线程阻塞 I/O。

    非阻塞线程应该能够在其他线程阻塞时在套接字上发送(我已经编写了这样的代码)。

    【讨论】:

    • 只有当系统调用支持所有东西的非阻塞调用时才有可能。很有可能在 fstat 之类的东西上停止所有用户线程几秒钟。
    • @Zan Lynx:他说的是 Linux,它具有符合 POSIX 标准的 aio_read() 和 aio_write() 系统调用。
    • 你注意到我说“像 fstat”了吗?这是一个没有我知道的异步版本的 POSIX 调用。还有其他的。
    猜你喜欢
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 2014-04-03
    • 2013-04-21
    • 2023-03-06
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    相关资源
    最近更新 更多