【发布时间】:2014-11-08 08:36:36
【问题描述】:
我有两个关于线程的问题,一个是关于竞争条件的,另一个是关于互斥锁的。 所以第一个问题: 我在 wikipedia page 中阅读了有关比赛条件的信息: http://en.wikipedia.org/wiki/Race_condition
在 2 个线程之间的竞争条件示例中,如下所示: http://i60.tinypic.com/2vrtuz4.png[
到目前为止,我相信线程彼此并行工作,但从这张图片来看,我似乎解释了计算机如何执行错误的操作。 从这张图片来看,一次只完成一个动作,虽然线程不时切换并且另一个线程开始做一些动作,但这仍然是计算机一次完成一个动作。真的是这样吗?没有“真正的”并行计算,一次只能以非常快的速度完成一项操作,这给人一种并行计算的错觉?
这引出了我关于互斥锁的第二个问题。 我读过,如果线程读/写相同的内存,我们需要某种同步机制。我读过普通的数据类型不会做,我们需要一个互斥锁。 我们以下面的代码为例:
#include <stdio.h>
#include <stdbool.h>
#include <windows.h>
#include <process.h>
bool lock = false;
void increment(void*);
void decrement(void*);
int main()
{
int n = 5;
HANDLE hIncrement = (HANDLE)_beginthread(increment, 0, (void*)&n);
HANDLE hDecrement = (HANDLE)_beginthread(decrement, 0, (void*)&n);
WaitForSingleObject(hIncrement, 1000 * 500);
WaitForSingleObject(hDecrement, 1000 * 500);
return 0;
}
void increment(void *p)
{
int *n = p;
for(int i = 0; i < 10; i++)
{
while (lock)
{
}
lock = true;
(*n)++;
lock = false;
}
}
void decrement(void *p)
{
int *n = p;
for(int i = 0; i < 10; i++)
{
while (lock)
{
}
lock = true;
(*n)--;
lock = false;
}
}
现在在我的示例中,我使用布尔锁作为我的同步机制,以避免 2 个线程之间在指针 n 指向的内存空间上发生争用情况。 现在我在这里所做的显然不会奏效,因为虽然我避免了两个线程之间指针 n 指向的内存空间的竞争条件,但可能会发生 bool lock 变量的新竞争条件。
让我们考虑以下事件序列(A = 递增线程,B = 递减线程):
- 由于锁为假,A 退出了 while 循环
- A 可以将 lock 设置为 true
- B 在 while 循环中等待,因为 lock 设置为 true
- 增加n所指向的值
- A 将 lock 设置为 false
- A 进入 while 循环
- 由于锁为假,A 退出了 while 循环
- B 退出 while 循环,因为锁为假
- A 将 lock 设置为 true
- B 将锁定设置为真
从这里我们得到 2 个非同步线程的意外行为,因为 bool 锁不是竞争条件证明。
好的,到目前为止,这是我的理解和解决我们上述问题的方法,我们需要一个互斥锁。 我很好,这是一种神奇地证明条件竞争的数据类型。 我只是不明白 mutex 类型不会像其他所有类型一样发生,这就是我的问题,我想了解为什么 mutex 以及这是如何发生的。
【问题讨论】:
-
您可以在多处理器系统上同时运行多个线程。
-
您不能使用 SO 来学习线程等新的专业知识。我建议你找到一个好的网站和教程并开始学习。您的问题表明您完全不知道线程是什么或它是如何工作的。
-
我认为这是一个完全有效的问题,尽管围绕它有很多额外的说明,这可能是由于对不熟悉的上下文有点困惑(我在自己的问题中发现了同样的趋势)。所以,我认为@Omlis532 之后的问题是:“当所有基本类型都不是线程安全时,线程安全互斥类型如何存在?”
-
@CarloWood 我没有说我说的一定是正确的,我说这是我的理解,这就是为什么我来这里并就试图理解的主题提出问题更多的。对我说你不理解它去互联网阅读它(虽然我做过)无论如何都没有帮助。
-
@Medo42 关于我的第二个问题是正确的 :)
标签: c multithreading mutex race-condition