一个线程读取,另一个写入volatile变量——线程安全?

时间:2021-07-09 00:39:59

In C I have a pointer that is declared volatile and initialized null.

在C中,我有一个指针,它被声明为volatile并初始化为null。

void* volatile pvoid;

Thread 1 is occasionally reading the pointer value to check if it is non-null. Thread 1 will not set the value of the pointer. Thread 2 will set the value of a pointer just once.

线程1偶尔会读取指针值,以检查它是否为非空。线程1不会设置指针的值。线程2将只设置一次指针的值。

I believe I can get away without using a mutex or condition variable.
Is there any reason thread 1 will read a corrupted value or thread 2 will write a corrupted value?

我相信我不用互斥体或条件变量就能逃脱惩罚。线程1读取已损坏值或线程2写入已损坏值有何原因?

6 个解决方案

#1


2  

In the case where the value fits in a single register, such as a memory aligned pointer, this is safe. In other cases where it might take more than one instruction to read or write the value, the read thread could get corrupted data. If you are not sure wether the read and write will take a single instruction in all usage scenarios, use atomic reads and writes.

如果值适合于一个寄存器(如内存对齐指针),那么这是安全的。在其他情况下,读取或写入值可能需要多个指令,读线程可能会得到损坏的数据。如果您不确定读和写在所有使用场景中是否只接受一条指令,那么使用原子读和写。

#2


3  

To make it thread safe, you have to make atomic reads/writes to the variable, it being volatile is not safe in all timing situations. Under Win32 there are the Interlocked functions, under Linux you can build it yourself with assembly if you do not want to use the heavy weight mutexes and conditional variables.

为了使它线程安全,您必须对变量进行原子读/写,在所有计时情况下,它都是不安全的。在Win32下有一些互锁的函数,在Linux下,如果您不想使用重量级的互斥和条件变量,那么您可以使用汇编来构建它。

If you are not against GPL then http://www.threadingbuildingblocks.org and its atomic<> template seems promising. The lib is cross platform.

如果您不反对GPL,那么http://www.threadingbuildingblocks.org及其原子化的<>模板看起来很有前途。**党是跨平台的。

#3


0  

Unfortunately, you cannot portably make any assumptions about what is atomic in pure C.

不幸的是,您不能对纯C中的原子做任何可移植的假设。

GCC, however, does provide some atomic built-in functions that take care of using the proper instructions for many architectures for you. See Chapter 5.47 of the GCC manual for more information.

然而,GCC确实提供了一些原子内置函数,这些函数可以帮助您为许多体系结构使用正确的指令。有关更多信息,请参阅GCC手册第5.47章。

#4


0  

Well this seems fine.. The only problem will happen in this case let thread A be your checking thread and B the modifying one.. The thing is that checking for equality is not atomic technically first the values should be copied to registers then checked and then restored. Lets assume that thread A has copied to register, now B decides to change the value , now the value of your variable changes. So when control goes back to A it will say it is not null even though it SHUD be according to when the thread was called. This seems harmless in this program but MIGHT cause problems..

这似乎很好. .在这种情况下,唯一的问题是让线程A作为检查线程,而线程B作为修改线程。问题是,检查是否相等并不是原子技术,首先应该将值复制到寄存器,然后进行检查,然后恢复。假设线程A已经复制来注册,现在B决定改变值,现在变量的值改变了。当控件返回到A时,它会说它不是空的,尽管它会根据线程被调用的时间来关闭。这在本程序中似乎是无害的,但可能会引起问题。

Use a mutex.. simple enuf.. and u can be sure you dont have sync errors!

使用互斥锁. .简单enuf . .你可以确定你没有同步错误!

#5


0  

Depends on your compiler, architecture and operating system. POSIX (since this question was tagged pthreads Im assuming we're not talking about windows or some other threading model) and C don't give enough constraints to have a portable answer to this question.

取决于您的编译器、体系结构和操作系统。POSIX(由于这个问题被标记为pthreads,假设我们不是在讨论windows或其他线程模型)和C没有提供足够的约束来获得这个问题的可移植答案。

The safe assumption is of course to protect the access to the pointer with a mutex. However based on your description of the problem I wonder if pthread_once wouldn't be a better way to go. Granted there's not enough information in the question to say one way or the other.

当然,安全的假设是使用互斥对象保护对指针的访问。但是,根据您对问题的描述,我想知道pthread_once是否不是更好的方法。当然,这个问题中没有足够的信息来说明这个或那个问题。

#6


-2  

On most platforms where a pointer value can be read/written in a single instruction, it either set or it isn't set yet. It can't be interrupted in the middle and contain a corrupted value. A mutex isn't needed on that kind of platform.

在大多数可以在一条指令中读取/写入指针值的平台上,要么设置指针值,要么尚未设置指针值。它不能在中间被中断,并且包含一个损坏的值。在这种平台上不需要互斥对象。

#1


2  

In the case where the value fits in a single register, such as a memory aligned pointer, this is safe. In other cases where it might take more than one instruction to read or write the value, the read thread could get corrupted data. If you are not sure wether the read and write will take a single instruction in all usage scenarios, use atomic reads and writes.

如果值适合于一个寄存器(如内存对齐指针),那么这是安全的。在其他情况下,读取或写入值可能需要多个指令,读线程可能会得到损坏的数据。如果您不确定读和写在所有使用场景中是否只接受一条指令,那么使用原子读和写。

#2


3  

To make it thread safe, you have to make atomic reads/writes to the variable, it being volatile is not safe in all timing situations. Under Win32 there are the Interlocked functions, under Linux you can build it yourself with assembly if you do not want to use the heavy weight mutexes and conditional variables.

为了使它线程安全,您必须对变量进行原子读/写,在所有计时情况下,它都是不安全的。在Win32下有一些互锁的函数,在Linux下,如果您不想使用重量级的互斥和条件变量,那么您可以使用汇编来构建它。

If you are not against GPL then http://www.threadingbuildingblocks.org and its atomic<> template seems promising. The lib is cross platform.

如果您不反对GPL,那么http://www.threadingbuildingblocks.org及其原子化的<>模板看起来很有前途。**党是跨平台的。

#3


0  

Unfortunately, you cannot portably make any assumptions about what is atomic in pure C.

不幸的是,您不能对纯C中的原子做任何可移植的假设。

GCC, however, does provide some atomic built-in functions that take care of using the proper instructions for many architectures for you. See Chapter 5.47 of the GCC manual for more information.

然而,GCC确实提供了一些原子内置函数,这些函数可以帮助您为许多体系结构使用正确的指令。有关更多信息,请参阅GCC手册第5.47章。

#4


0  

Well this seems fine.. The only problem will happen in this case let thread A be your checking thread and B the modifying one.. The thing is that checking for equality is not atomic technically first the values should be copied to registers then checked and then restored. Lets assume that thread A has copied to register, now B decides to change the value , now the value of your variable changes. So when control goes back to A it will say it is not null even though it SHUD be according to when the thread was called. This seems harmless in this program but MIGHT cause problems..

这似乎很好. .在这种情况下,唯一的问题是让线程A作为检查线程,而线程B作为修改线程。问题是,检查是否相等并不是原子技术,首先应该将值复制到寄存器,然后进行检查,然后恢复。假设线程A已经复制来注册,现在B决定改变值,现在变量的值改变了。当控件返回到A时,它会说它不是空的,尽管它会根据线程被调用的时间来关闭。这在本程序中似乎是无害的,但可能会引起问题。

Use a mutex.. simple enuf.. and u can be sure you dont have sync errors!

使用互斥锁. .简单enuf . .你可以确定你没有同步错误!

#5


0  

Depends on your compiler, architecture and operating system. POSIX (since this question was tagged pthreads Im assuming we're not talking about windows or some other threading model) and C don't give enough constraints to have a portable answer to this question.

取决于您的编译器、体系结构和操作系统。POSIX(由于这个问题被标记为pthreads,假设我们不是在讨论windows或其他线程模型)和C没有提供足够的约束来获得这个问题的可移植答案。

The safe assumption is of course to protect the access to the pointer with a mutex. However based on your description of the problem I wonder if pthread_once wouldn't be a better way to go. Granted there's not enough information in the question to say one way or the other.

当然,安全的假设是使用互斥对象保护对指针的访问。但是,根据您对问题的描述,我想知道pthread_once是否不是更好的方法。当然,这个问题中没有足够的信息来说明这个或那个问题。

#6


-2  

On most platforms where a pointer value can be read/written in a single instruction, it either set or it isn't set yet. It can't be interrupted in the middle and contain a corrupted value. A mutex isn't needed on that kind of platform.

在大多数可以在一条指令中读取/写入指针值的平台上,要么设置指针值,要么尚未设置指针值。它不能在中间被中断,并且包含一个损坏的值。在这种平台上不需要互斥对象。