这是竞争条件吗?

9 multithreading race-condition

竞争条件的定义:竞争条件或竞赛危险是系统或过程中的缺陷,其中过程的输出或结果出乎意料地且严重地依赖于其他事件的顺序或时间.

考虑以下伪代码:

    Global variable i initialized to 6;
    Thread 1: 
        acquire(lock l)
        increment global variable i, i.e. i++;

    Thread 2: 
       acquire(lock l)
       double the value of global var i, i.e.: i*=2;
Run Code Online (Sandbox Code Playgroud)

如果T1首先获得锁定l并且T2获得T2秒,则i的值将为14.另一方面,如果T2首先获得锁定l并且T1获得第二锁定,则i的值将是13.

那么,这是不是竞争条件?

更新:经过多次评论和回答后,意见仍然存在分歧.我的观点是"是的,这是竞争条件"类别.实际上我把这个例子作为竞争条件情况,在另一个问题上.与此同时,我还在"不,这不是竞争条件"类别中阅读了一些有趣的评论.我想我会解决并得出结论认为这是一种竞争条件,取决于观察问题的视角/水平.但是,我还在等待有趣的答案/评论.

Mic*_*urr 8

我认为示例算法是否具有竞争条件取决于算法预期要做什么.

修改没有数据竞争i- 这些访问是序列化的,并且相对于彼此原子地发生.

但是,如果对于算法的正确性而言,增量在乘法之前发生是很重要的(反之亦然),则必须使用竞赛,并且必须使用其他方法来同步算法的执行.如果算法被认为是一种复杂的计算方法i * 2 + 1(尽管使用线程执行计算可能是荒谬的),那么就存在竞争条件.

请考虑以下程序片段:

int data;

pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;

void* wait_for_data(void*)
{
    pthread_mutex_lock( &mux);
    pthread_cond_wait( &condvar, &mux);

    puts("got the data: %d\n", data);

    pthread_mutex_unlock( &mux);

    return 0;
}


void* set_data(void*)
{
    pthread_mutex_lock( &mux);

    data = 42;

    pthread_cond_signal( &condvar);

    pthread_mutex_unlock( &mux);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

两个线程基本上完全互斥 - 没有数据竞争.但是,如果在等待它set_data()之前发出条件变量的信号wait_for_data(),wait_for_data()则永远不会完成.我认为大多数人会因为不正确使用条件变量而将其称为竞争条件.

  • 为什么这个在-1? (3认同)

Mar*_*nen -1

是的。根据定义,它是。此外,您还会遇到波动性可变的问题。在这种情况下,无法保证哪个线程将变量从内存加载到哪个寄存器,然后将其保存到内存。因此,在某些情况下,一个线程可能会获得陈旧的值。在许多语言中,您必须以某种方式确保始终获取干净的副本。(在java中易失性)

http://www.freebsd.org/doc/en/books/developers-handbook/secure-race-conditions.html

我认为这也是一个很好的定义。

阅读:http://dl.acm.org/itation.cfm? id=130623

“隐含地考虑了两种不同的概念:一种与旨在确定性的程序(我们称之为一般竞争)有关,另一种与包含关键部分的非确定性程序(我们称之为数据竞争)有关。”

因此,如果您假设该程序始终产生相同的结果,我会说这是一场“一般竞赛”。如果没有,你的设计就非常奇怪。

  • @Markus,你错了。根据定义,锁可以增强内存一致性。“锁”前面会有一个“加载内存栅栏”,“解锁”后面会有一个“存储内存栅栏”。 (2认同)