有必要同步全局变量的使用

时间:2013-10-27 19:18:21

标签: c++ multithreading synchronization pthreads

我有这个代码,这里需要同步使用全局变量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;
}

3 个答案:

答案 0 :(得分:1)

是的,您需要保护对全局变量的访问。您需要使用mutex或者需要使用atomic类型(包括atomit操作来修改它们)。

如果不这样做,问题是普通+=需要读操作,添加一些值然后将结果写回内存。如果两个线程同时执行此操作,它们可以重叠,例如,它们将在示例代码中读取0,然后两者都写入其结果,这意味着最后一次写入操作获胜,因此另一个添加将丢失。您最终得到的是27,而不是9

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

在SMP机器(具有单独的数据高速缓存存储器)中,还有另一个微妙的考虑因素,即线程间内存同步。如果线程在不同的内核/ CPU中运行,即使更新c的两个线程没有完全同时运行,它们也可能不会立即看到来自另一个线程的内存更新。例如,使用pthread_mutex_t进行同步将解决此问题。

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

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