0

我有这段代码,这里需要同步全局变量 c 的使用吗?流将同时开始工作并且一个线程将覆盖另一个线程的结果并最终得到 2 或 7 是否可行?

#include <iostream>
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h>

int c = 0;

void* write(void*)
{
    c += 2;
}

void* read(void*)
{
    c += 7; 
}

int main()
{
    pthread_t t1;
    pthread_t t2;

    std::cout << "first C = " << c << std::endl;
    int r1 = pthread_create(&t1, 0, &write, 0);
    int r2 = pthread_create(&t2, 0, &read, 0);
    pthread_join(t1, 0);
    pthread_join(t2, 0);
    std::cout << " C = " << c << std::endl;

    return 0;
}
4

3 回答 3

1

是的,您需要保护对全局变量的访问。您要么需要使用互斥体,要么需要使用原子类型(包括修改它们的原子操作)。

如果你不这样做,问题是正常+=需要读取操作,添加一些值,然后将结果写回内存。如果两个线程同时执行此操作,它们可能会重叠,例如,它们都将读取0您的示例代码,然后都写入它们的结果,这意味着最后一个写入操作获胜,因此另一个添加操作丢失。你最终得到27代替9你已经怀疑的那样。

于 2013-10-27T19:24:04.577 回答
1

如果您有多个线程可能同时访问一个对象,并且至少其中一个线程更改了该对象,那么除非对对象的访问是同步的,否则您将发生数据竞争。如果您有数据竞争,则程序的行为是未定义的。

也就是说,是的,您需要c使用适当的同步访问。

于 2013-10-27T19:26:02.780 回答
0

在 SMP 机器(具有单独的数据缓存存储器)中,还有一个微妙的事情需要考虑,那就是线程间内存同步。如果线程在不同的内核/CPU 中运行,即使更新的两个线程的c运行时间不完全相同,它们也可能不会立即看到另一个线程的内存更新。例如使用pthread_mutex_t同步将解决这个问题。

请注意,pthread_join()将内存与其他线程同步,因此在加入线程后不需要额外的措施来保证c看到其更新的值。

以下是保证与其他线程提供内存同步的 POSIX 线程函数列表:http: //pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11

于 2013-11-06T03:17:42.313 回答