Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C volatile变量而不是mutex保护变量,用于检查更改的数据_C_Pthreads - Fatal编程技术网

C volatile变量而不是mutex保护变量,用于检查更改的数据

C volatile变量而不是mutex保护变量,用于检查更改的数据,c,pthreads,C,Pthreads,我有一个线程,它基本上可以: int changed; //global variable .. for (;;) { pthread_mutex_lock(&mtx); if (changed) { do_changes(); changed = 0; } pthread_mutex_unlock(&mtx); do_stuff(); } 循环每秒运行几十万次,而全局changed变量很少(一天几次)由另一个线程

我有一个线程,它基本上可以:

int changed; //global variable
..

for (;;) {
   pthread_mutex_lock(&mtx);
   if (changed) {
       do_changes();
       changed = 0;
   }
   pthread_mutex_unlock(&mtx);

   do_stuff();

}
循环每秒运行几十万次,而全局
changed
变量很少(一天几次)由另一个线程设置

换成

volatile int changed; //global variable
..

for (;;) {

   if (changed) {
       pthread_mutex_lock(&mtx);
       do_changes();
       changed = 0;
       pthread_mutex_unlock(&mtx);
   }
   do_stuff();
}
我可以用这种方法测量循环3-4%的性能提高,这是值得追求的

然而,不稳定的变数似乎被极力劝阻。
这种方法有什么缺点吗?任何可能导致2。版本是否不能按预期工作?

最好将其设置为易失性,以确保编译器不会进行不必要的优化,但不会使其原子化

如果有更多线程正在读取“changed”,则当另一个线程正在等待执行do_changes()时,可能会发生一个线程将“changed”更新为0的情况,这将在释放互斥锁后发生,因为条件已被评估

如果要避免这种情况,请将If语句移动到互斥保护空间内

希望这有帮助


Carles.

最好将其设置为易失性,以确保编译器不会进行不必要的优化,但不会使其原子化

如果有更多线程正在读取“changed”,则当另一个线程正在等待执行do_changes()时,可能会发生一个线程将“changed”更新为0的情况,这将在释放互斥锁后发生,因为条件已被评估

如果要避免这种情况,请将If语句移动到互斥保护空间内

希望这有帮助


Carles.

最好将其设置为易失性,以确保编译器不会进行不必要的优化,但不会使其原子化

如果有更多线程正在读取“changed”,则当另一个线程正在等待执行do_changes()时,可能会发生一个线程将“changed”更新为0的情况,这将在释放互斥锁后发生,因为条件已被评估

如果要避免这种情况,请将If语句移动到互斥保护空间内

希望这有帮助


Carles.

最好将其设置为易失性,以确保编译器不会进行不必要的优化,但不会使其原子化

如果有更多线程正在读取“changed”,则当另一个线程正在等待执行do_changes()时,可能会发生一个线程将“changed”更新为0的情况,这将在释放互斥锁后发生,因为条件已被评估

如果要避免这种情况,请将If语句移动到互斥保护空间内

希望这有帮助


Carles。

volatile不会使变量线程安全或原子。你可能喜欢用它

基本上有两个线程在更改变量
changed
从而覆盖以前的值,从而导致数据争用


我不能推荐足够的观看。(它也适用于C)。

volatile
不会使变量线程安全或原子化。你可能喜欢用它

基本上有两个线程在更改变量
changed
从而覆盖以前的值,从而导致数据争用


我不能推荐足够的观看。(它也适用于C)。

volatile
不会使变量线程安全或原子化。你可能喜欢用它

基本上有两个线程在更改变量
changed
从而覆盖以前的值,从而导致数据争用


我不能推荐足够的观看。(它也适用于C)。

volatile
不会使变量线程安全或原子化。你可能喜欢用它

基本上有两个线程在更改变量
changed
从而覆盖以前的值,从而导致数据争用

我不能推荐足够的观看。(它也适用于C)。

作者:然而,易变变量似乎被严重劝阻。这种方法有什么缺点吗?任何可能导致2。版本无法按预期工作?

首先:当您尝试使用
volatile
时,如果您不需要,请重新考虑。
现在看看会发生什么:

1) 如果在多个线程中有循环,则不安全。您可以考虑复制支票:

if (changed) { // quick check
   pthread_mutex_lock(&mtx);
   if (changed) { // another thread could do the work
       ...
2) 如果您的代码很关键,您需要使用原子,因为
If(changed)
pthread\u mutex\u lock之前的
If(changed)
可能由于缓存而看不到它

3) 它可以在具有强内存顺序和原子int访问的x86(_64)上工作,但在其他体系结构上失败。这就是为什么
volatile
不受欢迎的原因,请使用原子学(并养成习惯)
volatile
不强制原子使用或任何其他同步
。原子学do(读修改写指令)

std::原子_标志已验证;
std::互斥体mx;结构MyData{…}数据;
无效更改(){
锁和防护锁(mx);
数据;
已验证。清除();
}
void validate(){
如果(!validated.test_和_set()){
锁和防护锁(mx);
data.update();
}
}
注意:除非您持有锁并使用另一个变量,否则您永远无法确定数据是否有效

4) 只需使用pthread\u spinlock\t尝试您的原始代码即可

5) 小建议:除非你真的知道自己在做什么,否则不要把同步当成上帝。您可以从互斥切换到自旋锁(由其他人编写),并进行一些基准测试

关于编辑和评论:最初的答案只是从1)之前什么都没有开始。事实证明,有些人既没有读完整的问题,也没有读完整的答案。皮蒂是那些情绪低落的选民。这个网站不是facebook,这些投票应该是Either是helpf
std::atomic_flag validated;
std::mutex mx; struct MyData { ... } data;
void change() {
    lock_guard<mutex> lock(mx);
    data.something();
    validated.clear();
}
void validate() {
    if(!validated.test_and_set()) {
        lock_guard<mutex> lock(mx);
        data.update();
    }
}