互斥体出错了?
Mutex gone wrong?
我正在尝试Pthreads及其非常基本的程序:我在所有线程中有两个共享变量(声明为全局)
long Sum = 0;
long Sum1 = 0;
pthread_mutex_t mutexLock = PTHREAD_MUTEX_INITIALIZER;
在线程函数中:
for(int i=start; i<end; i++) //start and end are being passed to thread and they are being passed correctly
{
pthread_mutex_lock(&mutexLock);
Sum1+=i;
Sum+=Sum1;
pthread_mutex_unlock(&mutexLock);
}
main() 以防万一需要参考:
int main()
{
pthread_t threadID[10];
for(int i=0; i<10; i++)
{
int a = (i*500) + 1;
int b =(i + 1)*500;
ThreadStruct* obj = new ThreadStruct(a,b);
pthread_create(&threadID[i],NULL,ThreadFunc,obj);
}
for(int i=0; i<10; i++)
{
pthread_join(threadID[i], NULL);
}
cout<<"Sum: "<<Sum<<endl;
cout<<"Sum1: "<<Sum1<<endl;
return 0;
}
输出
总和: 40220835000 总 1: 12502500
再次运行
总和: 38720835000 总 1: 12502500
再次运行
总和: 39720835000 总 1: 12502500
问题
为什么我在每次迭代中都会获得不同的Sum
值?其余整个代码工作正常,Sum1 的输出是正确的 - 无论我运行代码多少次。(唯一的问题是总和)。我在这里使用互斥锁做错了吗?
更新
如果我按照他详细的答案@molbdnilo指定的那样使用局部变量,这个问题就解决了。一开始,我认为互斥锁在这里无关紧要,但我多次测试了它,并观察到不使用互斥锁导致此问题再次出现的情况。因此,这个问题的解决方案(礼貌:@molbdnilo回答)是将局部变量与互斥体一起使用,我已经测试了它以完美工作!
这不是线程问题 - 问题是,即使Sum1
的添加顺序无关紧要,但Sum
的添加顺序却很重要。
考虑更短的总和 1 + 2 + 3 和以下交错
1:
Sum1 = 1 + 2 = 3
Sum = 0 + 3 = 3
Sum1 = 3 + 3 = 6
Sum = 3 + 6 = 9
阿拉伯数字:
Sum1 = 1 + 3 = 4
Sum = 0 + 4 = 4
Sum1 = 4 + 2 = 6
Sum = 4 + 6 = 10
3:
Sum1 = 2 + 3 = 5
Sum = 0 + 5 = 5
Sum1 = 5 + 1 = 6
Sum = 5 + 6 = 11
您可以通过让线程独立计算自己的总和并在之后添加它们来解决此问题。
(请注意,这里没有并发突变,因此锁定任何内容都没有任何区别。
对于更具体的例子,让我们将程序限制为两个线程,总和从 1 到 6。
然后,您有一个线程计算1 + 2 + 3
,另一个线程计算4 + 5 + 6
。
一目了然,线程 1 还应该计算1 + (1 + 2) + (1 + 2 + 3)
和线程 2,4 + (4 + 5) + (4 + 5 + 6)
。
除了他们没有 - 每次他们使用它时,Sum
可能已被另一个线程修改。
所以线程一可以计算1 + ((1 + 4) + 2) + ((1 + 4) + 2 + 3)
,或者别的什么。
使用局部变量时,可以使每个线程的结果独立于其他线程。
(顺便说一下,我认为这个问题很好地说明了共享可变状态如何以意想不到的方式使事情复杂化。
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- 首要问题的答案让值班员搞错了
- 看起来is_nothrow_constructible_v()在MSVC中被破坏了,我错了吗
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 我的C++线程做错了什么?
- 如何正确使用 >=?(a+f()+c)>=0 错了吗?
- 谁能告诉我我用 getline 做错了什么 (cpp) 格式
- 没有输出的合并排序我做错了什么?
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 在C++中使用 AKS 素数测试计算双胞胎素数 我做错了什么?
- 指针相关的UE4崩溃.我的指针哪里错了?
- 我一直试图弄清楚我在这个链表程序中做错了什么
- 我正在尝试学习如何在 c++ 中传递指针,但出现错误:没有用于调用"test"的匹配函数。我做错了什么?
- FFMPEG,C++,内存泄漏,我做错了什么?
- 我做错了什么?反向字符串 C++
- 我在这个课上做错了什么?
- 我在尝试将多个值push_back向量时出错。我做错了什么?
- 过载时出错 <<。我在这里做错了什么?
- 使用针对Win32的英特尔C++编译器编译Qt时出错,我做错了什么