簡體   English   中英

一個線程讀取和另一個寫入volatile變量 - 線程安全?

[英]One thread reading and another writing to volatile variable - thread-safe?

在CI中有一個聲明為volatile且初始化為null的指針。

void* volatile pvoid;

線程1偶爾讀取指針值以檢查它是否為非空。 線程1不會設置指針的值。 線程2只會將指針的值設置一次。

我相信我可以在不使用互斥鎖或條件變量的情況下逃脫。
是否有任何原因線程1將讀取損壞的值或線程2將寫入損壞的值?

為了使線程安全,你必須對變量進行原子讀/寫操作,它在所有時序情況下都是不安全的。 在Win32下有Interlocked函數,在Linux下你可以自己用程序集自己構建它,如果你不想使用重量級互斥和條件變量。

如果您不反對GPL,那么http://www.threadingbuildingblocks.org及其atomic<>模板似乎很有希望。 lib是跨平台的。

在值適合單個寄存器的情況下,例如內存對齊指針,這是安全的。 在其他可能需要多條指令來讀取或寫入值的情況下,讀取線程可能會損壞數據。 如果您不確定讀取和寫入是否會在所有使用場景中執行單個指令,請使用原子讀取和寫入。

不幸的是,你無法對純C中的原子進行任何假設。

但是,GCC確實提供了一些原子內置函數,這些函數負責為您使用適當的指令。 有關詳細信息,請參閱GCC手冊的第5.47章

好吧這看起來很好..唯一的問題是在這種情況下會發生讓線程A成為你的檢查線程而B是修改的線程。問題是檢查相等性在技術上不是首先應該將值復制到寄存器然后檢查並且然后恢復。 讓我們假設線程A已復制到寄存器,現在B決定更改值,現在變量的值會發生變化。 因此,當控制返回到A時,它會說它不是空的,即使SHUD是根據調用線程的時間。 這在程序中似乎無害,但可能導致問題。

使用互斥...簡單的enuf ..你可以確定你沒有同步錯誤!

取決於您的編譯器,體系結構和操作系統。 POSIX(因為這個問題被標記為pthreads我假設我們不是在談論窗口或其他一些線程模型)而且C沒有給出足夠的約束來對這個問題進行可移植的回答。

安全的假設當然是用互斥鎖來保護對指針的訪問。 但是根據您對問題的描述,我想知道pthread_once是不是更好的方法。 當然,問題中的信息不足以說明這種或那種方式。

在大多數可以在單個指令中讀取/寫入指針值的平台上,它既可以設置,也可以不設置。 它不能在中間中斷並包含損壞的值。 在那種平台上不需要互斥鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM