2017-10-17 271 views
2

互斥锁是否按照它们被调用的顺序赋予了这些线程?所以说我们有三个线程A,B和C以及一个互斥锁mtx。如果A首先调用mtx.lock(),然后B和C,那么这是否意味着A首先获得锁,然后是B,然后是C.如果不是,我怎么能保证它?互斥锁的顺序

+2

这是一个真正的问题。一个[mcve]会变成一个好问题。 (注意:我认为OP知道线程A将首先获得锁,它们的问题的核心是线程B和C的锁定顺序) – YSC

+0

“A”将首先获得锁,但不保证“ B“和”C“ – AhmadWabbi

+0

有没有办法强制B的顺序,然后C? – Rishi

回答

1

如果多个线程正在等待互斥锁,则会选择一个等待线程。不要采用先入先出(FIFO)的顺序。外部事件(如内核模式APC)可以更改等待顺序。 - 从MSDN,关于Mutex对象的页面。

见链接: Mutex Objects

+0

在这种情况下,我可以使用什么来保证订单? – Rishi

+0

该链接似乎是关于某些平台特定的互斥API。但没有迹象表明提问者使用的不是标准C++(即'std :: mutex')。 –

+0

没有指定哪个线程将在当前所有者解锁互斥锁时收到互斥锁的所有权(我的意思是std :: mutex) –

0

我有一个简单的例子来证明这一点,我创建3项任务,其中获取锁,打印的东西,然后完成等待加入。你可以玩这个,而不是设置障碍(3),你可以将它设置为(2),让task_a运行,让另外两个对抗锁。

我使用boost :: barrier来确保它们在创建时不会立即启动。结果是一个不确定的命令,而不是FIFO。不同的平台会给你不同的结果。 A demo of it in action

std::mutex foo; 
boost::barrier bar(3); 

void task_a() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task a\n"; 
    foo.unlock(); 
} 

void task_b() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task b\n"; 
    foo.unlock(); 
} 

void task_c() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task c\n"; 
    foo.unlock(); 
} 

int main() 
{ 
    std::thread th1 (task_a); 
    std::thread th2 (task_b); 
    std::thread th3 (task_c); 
    th1.join(); 
    th2.join(); 
    th3.join(); 

    return 0; 
} 
+0

谢谢。你如何保证上述代码中的fifo命令? – Rishi

+0

你可以使用条件变量,一旦一个线程完成,你发出另一个线程去等第三个线程。 –

+0

我认为条件变量不能保证顺序吗?或者我是否必须以某种方式实现我的代码?所以说线程th2和th3都使用一个条件变量来等待th1,th2会被保证是下一个执行的 – Rishi