在不使用互斥锁的情况下保护双变量

时间:2012-02-21 05:07:58

标签: c multithreading gcc mutex

问候!!

我在Linux中运行了一个app,这是一个POSIX多线程应用程序, 在线程1中,我以这种方式设置全局变量:

Pthread_mutex_lock(&Mutex1); 
for(idx=0;idx<1000;idx++)
{
      Data1[idx].doubleval = idx * 100.0 * anothervar  ;
}//for 
Pthread_mutex_unlock(&Mutex1); 
在thread2中,我以这种方式得到全局变量:

Pthread_mutex_lock(&Mutex1); 
for(idx=0;idx<1000;idx++)
{
     doublexxx = Data1[idx].doubleval ;
     DoSomething(doublexxx) ;
}//for 
Pthread_mutex_unlock(&Mutex1); 

现在,假设我不想在我的ap中使用Mutex,如果thread1正在设置Data1 [33] .doubleval而thread2正在读取Data1 [33] .doubleval,那么Data1 [33] .doubleval会非常奇怪价值?我的意思是,例如,double var有4个字节,而thread1设置Data1 [33] .doubleval前2个字节,后来没有完成2个字节,在这个位置 thread2试图读取Data1 [33] .doubleval ....有可能吗?

如果有可能,如何在没有此类问题的情况下保护双变量? 互斥是很好用的,我只是想知道是否有另一种方法来保护双变量 哪个thread1正在写入,至少thread2尝试从同一个var读取 将等待4个字节的双倍完成!!!

2 个答案:

答案 0 :(得分:1)

要担心的问题不是写入中途读取的价值;我不知道这是可行的系统。问题是你的第二个线程的行为将是未定义的,因为你不知道它是否会在第一个线程写入给定的内存部分之前或之后读取。如果没有互斥体或功能相同的东西,就无法获得明确定义的行为。

答案 1 :(得分:1)

是否可以读取“部分写入”值取决于大量因素(例如目标系统和对齐),并且绝对不可移植。例如,假设这个代码在16位CPU上运行,浮点支持在软件中模拟。

即使使用互斥锁,第二个线程的行为仍然是未定义的,因为它不知道它是在第一个线程写入之前还是在第一个线程写入之后读取数据。

我怀疑您的设计存在更高级别的问题 - 也许您应该使用条件变量来使第二个线程等到第一个线程写入之后。

我还怀疑你要求删除互斥锁的原因是为了提高可扩展性/性能。例如,使一个线程使用数组的一部分,而另一个线程修改同一数组的完全不同的部分。如果这是你的问题背后的原因,那么解决方案取决于你的场景 - 它可以像使用多个锁一样简单(阵列的每个区域一个互斥锁,每个条目最多一个互斥锁),但可能意味着实现“读者” / writer“lock(允许多个线程同时从数组中读取,只要没有其他线程正在写入)。