相关疑难解决方法(0)

使用std :: atomic和std :: condition_variable,Sync是不可靠的

在用C++ 11编写的分布式作业系统中,我使用以下结构实现了一个fence(即工作线程池外部的线程可能会要求阻塞,直到完成所有当前计划的作业):

struct fence
{
    std::atomic<size_t>                     counter;
    std::mutex                              resume_mutex;
    std::condition_variable                 resume;

    fence(size_t num_threads)
        : counter(num_threads)
    {}
};
Run Code Online (Sandbox Code Playgroud)

实现fence的代码如下所示:

void task_pool::fence_impl(void *arg)
{
    auto f = (fence *)arg;
    if (--f->counter == 0)      // (1)
        // we have zeroed this fence's counter, wake up everyone that waits
        f->resume.notify_all(); // (2)
    else
    {
        unique_lock<mutex> lock(f->resume_mutex);
        f->resume.wait(lock);   // (3)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果线程在一段时间内进入围栏,这种方法非常有效.然而,如果他们几乎同时尝试这样做,似乎有时会发生在原子递减(1)和开始条件var(3)的等待之间,线程产生CPU时间而另一个线程将计数器递减到零( 1)并解雇cond.var(2).这导致前一个线程在(3)中永远等待,因为它已经被通知后开始等待它.

让事情变得可行的黑客就是在(2)之前进行10毫秒的睡眠,但这显然是不可接受的.

有关如何以高效的方式解决这个问题的任何建议?

c++ multithreading stl c++11

11
推荐指数
1
解决办法
2651
查看次数

发送条件变量信号时必须保持锁定吗?

好的。此处的示例是使用 c 中的 pthread lib 提供的。

在教科书中,我遇到了以下代码:

//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
Run Code Online (Sandbox Code Playgroud)

这段代码运行良好。我只是想知道以下代码是否也有效?

//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);//signal the conditional variable but the lock is not held
Run Code Online (Sandbox Code Playgroud)

以下代码的优缺点是什么?

附注。假设协作线程有代码:

//for thread 1
pthread_mutex_lock(&lock);
while(!should_wake_up)
    pthread_cond_wait(&cond, &lock);
pthead_mutex_unlock(&lock);
Run Code Online (Sandbox Code Playgroud)

PS2。我遇到了其他一些问题,它指出如果我们不希望信号丢失,我们必须使用锁来确保在持有锁时不能更改关联的谓词(在这种情况下,是 should_wake_up)线程 1. 在这种情况下,这似乎不是问题。链接到帖子:[1]:在不持有锁的情况下在条件变量上发出信号。我认为他的问题是他忘记了锁定。但我的问题是不同的。

multithreading pthreads

3
推荐指数
1
解决办法
98
查看次数

标签 统计

multithreading ×2

c++ ×1

c++11 ×1

pthreads ×1

stl ×1