暂停和恢复pthreads的最佳解决方案是什么?

Che*_*aoh 12 c++ posix pthreads

我找到了关于pthreads 的以下主题(这里),但有很多很好的解决方案.

我想知道以下代码是否有效,如果是,为什么使用相同的锁来调用pthread_cond_wait以及访问它然后立即解锁:

void suspendMe()
{
    pthread_mutex_lock(&m_SuspendMutex);
    pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
    pthread_mutex_unlock(&m_SuspendMutex);
}
Run Code Online (Sandbox Code Playgroud)

在这里使用2个单独的互斥锁不是更好吗,或者这是暂停pthread的正确方法?

提前致谢!

编辑:

很棒的回复,谢谢大家.还有一个相关的问题.既然我想在另一个函数中单独恢复一个线程,那么恢复它会更合适吗?

void suspendMe()
{
    pthread_mutex_lock(&m_SuspendMutex);
    pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
}
void resumeMe()
{
    pthread_cond_signal(&m_ResumeCond);
    pthread_mutex_unlock(&m_SuspendMutex);
}
Run Code Online (Sandbox Code Playgroud)

再次感谢大家!:〜)

Dav*_*rtz 8

实际上,这段代码不是线程安全的.互斥体实际上并没有保护任何东西,使隐含的谓词容易受到竞争条件的影响.

看看这段代码 - 互斥保护是什么?什么保护暂停/恢复状态?

void suspendMe()
{
    pthread_mutex_lock(&m_SuspendMutex);
    pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
}
void resumeMe()
{
    pthread_cond_signal(&m_ResumeCond);
    pthread_mutex_unlock(&m_SuspendMutex);
}
Run Code Online (Sandbox Code Playgroud)

这是对的:

void suspendMe()
{ // tell the thread to suspend
    pthread_mutex_lock(&m_SuspendMutex);
    m_SuspendFlag = 1;
    pthread_mutex_unlock(&m_SuspendMutex);
}
void resumeMe()
{ // tell the thread to resume
    pthread_mutex_lock(&m_SuspendMutex);
    m_SuspendFlag = 0;
    phtread_cond_broadcast(&m_ResumeCond);
    pthread_mutex_unlock(&m_SuspendMutex);
}
void checkSuspend()
{ // if suspended, suspend until resumed
    pthread_mutex_lock(&m_SuspendMutex);
    while (m_SuspendFlag != 0) pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
    pthread_mutex_unlock(&m_SuspendMutex);
}
Run Code Online (Sandbox Code Playgroud)

线程应该checkSuspend在可以挂起的安全点调用.其他线程可以调用suspendMeresumeMe挂起/恢复线程.

请注意,现在互斥锁保护m_SuspendFlag变量,确保线程被告知暂停,告知恢复,并检查它是否应该暂停或保持暂停状态,使代码线程安全.

在这里使用2个单独的互斥锁不是更好吗,或者这是暂停pthread的正确方法?

使用两个互斥量会破坏条件变量的整个点.它们工作的整个机制是你可以检查是否有你应该等待的东西然后原子地等待它,而不是在你等待或必须释放锁然后等待时持有锁.如果在等待时按住锁定,任何其他线程如何改变状态?如果您释放锁定然后等待,如果您错过了状态更改会发生什么?

顺便说一句,暂停或恢复一个线程几乎没有意义.如果您觉得需要从外部暂停一个线程,那只表示您编写了线程以执行您实际上不希望它执行的操作.关于暂停或恢复线程的问题通常表明线程编程的心理模型不正确.线程可能需要等待某些东西,但它不应该从外部"暂停",因为它应该已经知道它自己的编码什么时候它不应该做一些特定的工作.