挂起pthreads不使用条件

我想暂停pthreads,但显然没有pthread_suspend这样的函数。 我读了一些关于使用互斥锁和条件暂停pthread的地方,并使用它如下:

#include <pthread.h> class PThread { public: pthread_t myPthread; pthread_mutex_t m_SuspendMutex; pthread_cond_t m_ResumeCond; void start() { pthread_create(&myPthread, NULL, threadRun, (void*)this ); } Thread() { } void suspendMe() { pthread_cond_wait(&m_ResumeCond,&m_SuspendMutex); } void resume() { pthread_cond_signal(&m_ResumeCond); } }; 

但我不明白为什么我们需要互斥和条件暂停和恢复pthread。 不使用条件是否可以暂停和恢复?

Solutions Collecting From Web of "挂起pthreads不使用条件"

你的代码是不正确的 – pthread_cond_wait()要求当你调用它的时候,互斥锁已经被锁定了:

 void suspendMe() { pthread_mutex_lock(&m_SuspendMutex); pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex); pthread_mutex_unlock(&m_SuspendMutex); } 

但是,这仍然是错误的。 一个线程可以以任何名字从pthread_cond_wait()中唤醒,不一定只有当它被发信号时。 这意味着您需要将pthread_cond_wait()与一些共享状态进行配对,这些共享状态对线程正在等待的条件进行编码 – 最简单的情况下,您可以使用标志变量。 pthread_cond_signal()用于告诉线程应该唤醒并重新检查共享状态。 将此应用于您的实现:

 class PThread { public: pthread_t myPthread; bool suspended; pthread_mutex_t m_SuspendMutex; pthread_cond_t m_ResumeCond; void start() { suspended = false; pthread_create(&myPthread, NULL, threadRun, (void*)this ); } Thread() { } void suspendMe() { pthread_mutex_lock(&m_SuspendMutex); suspended = true; do { pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex); } while (suspended); pthread_mutex_unlock(&m_SuspendMutex); } void resume() { /* The shared state 'suspended' must be updated with the mutex held. */ pthread_mutex_lock(&m_SuspendMutex); suspended = false; pthread_cond_signal(&m_ResumeCond); pthread_mutex_unlock(&m_SuspendMutex); } }; 

提供互斥体的原因是为了保护共享状态并避免竞争条件pthread_cond_wait()函数在等待时实际执行原子解锁和等待,这可以避免“错过唤醒”。 例如在这段代码中,互斥锁可以防止在suspended = true;pthread_cond_wait()行。

如果一个线程没有在某种情况下等待,你怎么能“发信号”来恢复。 它不能停止执行任何事情,然后神奇地重新开始,所以它等待一个条件。

为了详细说明,在pthread中,恢复线程的方式实际上是使用条件变量。 没有可用的API以任何其他方式暂停/恢复线程。 在pthread_cond_wait等待是便宜的,它阻塞,直到条件信号,不使用(很多?)CPU。 您使用条件来通知线程唤醒,并且需要互斥锁来保护在唤醒时访问条件变量和线程中的代码。

一个条件总是与一个互斥体相关联。 通常情况下,一个线程会因为等待状态改变而表示有工作要做, 您需要使用互斥锁来保护对该状态的访问,以及发出更改的条件。

唤醒一个线程而不告诉它你为什么醒来这是一个有点奇怪的事情,所以没有特殊的方法来做到这一点。 唯一的办法是使用正常的机制,但没有共享状态。

如果由于某种原因,你想暂停并从另一个线程恢复线程,而不需要做任何工作,那么你可以使用pthread_kill来发送SIGSTOPSIGCONT信号。 我从来没有尝试过这样做,所以我不知道它是否被支持。

互斥体用于确保独占访问,其中条件变量用于根据事件同步线程。

我们需要Mutexes来确保条件变量不会以无限的等待结束。 有一点要记住的是,锁和解锁的互斥操作保证是原子的,但条件变量不一定是。 即,当条件变量等待一半时,线程可以被调度出来。

对于条件变量,考虑以下互斥互斥的情况。

主题1

1)执行一些操作
2)等待条件变量
3)继续操作

线程2

1)执行一些操作
2)发信号状态变量
3)继续操作

这里在线程1中,步骤2不保证是原子的。 如果线程1在完成step1之前被调度程序推出RUNNING状态。 现在线程2开始执行并发送条件变量。 当线程1恢复执行时,它将完成剩余的低级指令并开始等待。 线程1在无限等待中结束,因为条件变量的信号甚至在等待之前发生。

所以正确的使用方法是(我相信在问题中提到的代码不符合预期)

主题1: –

1)做一定的条件必须发生(如“计数”必须达到指定的值)
2)锁定关联的互斥锁
3)调用pthread_cond_wait()来阻塞等待来自线程1的信号。 (请注意,对pthread_cond_wait()的调用会自动并原子地解锁相关的互斥变量,以便Thread2可以使用它)
4)发信号时醒来。 互斥是自动和原子锁定的。
5)显式解锁互斥

线程2

1)工作
2)锁定关联的互斥锁
3)改变Thread1等待的全局变量的值。
4)检查全局Thread1等待变量的值。 如果满足所需条件,则发信号给Thread1。
5)解锁互斥。 继续

它看起来像没有任何Windows API SuspendThread函数的替代品。 在这个线程程序中,如果不注入任何代码,就不可能暂停Linux线程。

更重要的是 – 你最终想做什么? – 我怀疑答案不是“暂停线程”。 这可能是你的程序设计有问题。