时间:2018-06-09 15:13:14

标签: multithreading synchronization pthreads mutex

我发现了pthread库(在C中),并且我很难理解一些事情。

首先,我了解互斥锁是什么,我理解它是如何工作的,好吧,我也理解cond的概念,但我无法正确使用它(我不会这样做)真的得到如何结合互斥锁和cond)

这是伪代码,我想做的事情:

thread :
    loop :
        // do something
    end loop
end thread

所以有n个线程,但每个线程使用相同的函数。我希望循环的内部由所有线程并行执行但是每个线程必须在循环的同一次迭代中,这意味着我不关心循环中的指令在线程之间执行的顺序,但要开始一个线程的迭代2,所有其他线程必须完成迭代1(等)。 所以我的问题是:你是怎么做到的?特别是在一个具体的例子中,但在理论上。

修改

我设法做到了,我不知道它是否是正确的方式,但是它正在发挥作用:

global nbOfThreads
global nbOfIterations

thread :
    lock(mutex0)
    unlock(mutex0)
    loop :
        // Do something
        lock(mutex1)
        nbOfIterations++
        if (nbOfIterations == nbOfThread) :
            nbOfIterations = 0
            broadcast(cond)
            unlock(mutex1)
            continue
        end if

        wait(cond, mutex1)
        unlock(mutex1)
    end loop
end thread

main (n) :
    nbOfThreads = n
    nbOfIterations = 0
    lock(mutex0)
    do nbOfThreads times : create(thread) 
    unlock(mutex0)
end main

我显然试图了解自己,但有一些事情我不明白:

  • 主要原因:为什么cond需要与互斥锁配对
  • 在某些例子中,我看到了类似的内容:
// thread A :
while (!condition)
    wait(&cond)

// thread B :
if (condition)
    signal(&cond)
好吧,我真的不知道这个while循环的重点,我想等待线程暂停直到条件为真(直到另一个线程发送信号)。我的意思是,如果它是一个if而不是一段时间,我会得到它。

谢谢

2 个答案:

答案 0 :(得分:0)

为什么cond需要....因为你引用的(!条件)几乎肯定取决于引用它们时对象的某些位不会改变。相应地,修改对象的状态应该以对任何观察者来说都是原子的方式进行;因此是一个互斥体。虽然你可以依靠像原子类型这样过于聪明的hackery,但也存在“如果它在你检查之后被修改了怎么办”的问题 - 竞争条件。因此,惯用的锁(); while(!cond){wait(); }。

暂时的意义......信号+等待不是控制权的转移;在信号之后,在特定线程从等待返回之前,对象可能发生任何数量的事情。即使条件可能处于正确的状态,但是当线程A检查它时,它可能不再是。在退出while循环时,线程A知道:条件处于我想要的状态,并且我对该对象具有独占访问权。

答案 1 :(得分:0)

条件变量可能有虚假的唤醒。等待函数返回时,条件可能实际上不为真。

根据您的任务,可能更容易使用其他同步原语,例如屏障(请参阅pthread_barrier_init)或信号量(sem_init)。