multithreading - 这是比赛条件吗?

标签 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;

如果T1首先获取锁l,然后T2第二,则i的值为14。另一方面,如果T2首先获取锁l,然后T1其次,则i的值为13。

那么,这是否是比赛条件?

更新:经过大量评论和回答后,意见仍存在分歧。我的意见是“是的,这是一个竞赛条件”类别。实际上,在另一个问题上,我以竞争状况为例给出了此示例。
同时,我还阅读了“不,这不是比赛条件”类别中的一些有趣评论。
我想我会解决并得出结论,这是一种竞赛条件,还是不是一种竞赛条件,这取决于人们从哪个角度/水平看待问题。
但是,我仍在等待有趣的答案/评论。

最佳答案

我认为示例算法是否具有竞争条件取决于该算法的预期功能。

修改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;
}

这两个线程本质上是完全互斥的-没有数据争用。但是,如果set_data()发出信号通知条件变量,然后再等待wait_for_data()等待它,则wait_for_data()将永远不会完成。我认为大多数人会由于条件变量使用不当而将其称为竞争条件。

关于multithreading - 这是比赛条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12007205/

相关文章:

c# - 仅使用 async/await 时是否存在竞争条件?

ios - 在等待来自 Parse 的数据时,使用 swift 显示加载动画

c# - .NET - 检测到 ContextSwitchDeadlock

java - 在同一 channel 上消费和发布消息

c - 通过严格修改来防止比赛条件

javascript - 使用 jQuery AJAX 调用防止 "race conditions"

javascript - 在 Node.js 插件中使用 std::thread

java - 将单个可运行对象传递给多个线程构造函数

c# - 任务并行库 (TPL) 是否处理竞争条件

debugging - 检测 OpenMP 线程/CUDA 流之间的竞争条件