相关疑难解决方法(0)

一个什么都不做的函数有什么实际用途吗?

运行时不执行任何操作的函数有什么用处,即:

void Nothing() {}
Run Code Online (Sandbox Code Playgroud)

请注意,我不是在谈论等待一定时间的函数,例如sleep(),只是需要编译器/解释器给出的时间。

c function

79
推荐指数
10
解决办法
1万
查看次数

"锁定"指令在x86汇编中意味着什么?

我在Qt的源代码中看到了一些x86程序集:

q_atomic_increment:
    movl 4(%esp), %ecx
    lock 
    incl (%ecx)
    mov $0,%eax
    setne %al
    ret

    .align 4,0x90
    .type q_atomic_increment,@function
    .size   q_atomic_increment,.-q_atomic_increment
Run Code Online (Sandbox Code Playgroud)
  1. 从谷歌搜索,我知道lock指令将导致CPU锁定总线,但我不知道CPU何时释放总线?

  2. 关于以上整个代码,我不明白这段代码是如何实现的Add

c++ x86 assembly qt

59
推荐指数
3
解决办法
4万
查看次数

互斥锁功能是否足够而没有易失性?

我和同事为在x86,x64,Itanium,PowerPC和其他10年历史的服务器CPU上运行的各种平台编写软件.

我们刚刚讨论了pthread_mutex_lock()... pthread_mutex_unlock()等互斥函数本身是否足够,或者受保护变量是否需要是volatile.

int foo::bar()
{
 //...
 //code which may or may not access _protected.
 pthread_mutex_lock(m);
 int ret = _protected;
 pthread_mutex_unlock(m);
 return ret;
}
Run Code Online (Sandbox Code Playgroud)

我担心的是缓存.编译器是否可以在堆栈或寄存器中放置_protected的副本,并在赋值中使用该陈旧值?如果没有,是什么阻止了这种情况发生?这种模式的变化是否易受攻击?

我假设编译器实际上并不理解pthread_mutex_lock()是一个特殊函数,所以我们只是受序列点保护吗?

非常感谢.

更新:好的,我可以看到一个趋势,答案解释了为什么不稳定是坏的.我尊重这些答案,但有关该主题的文章很容易在网上找到.我在网上找不到的,以及我问这个问题的原因,就是我如何保护我没有不稳定.如果上面的代码是正确的,那么缓存问题如何无懈可击?

c++ multithreading mutex volatile memory-barriers

39
推荐指数
3
解决办法
7299
查看次数

pthread_mutex_lock是否包含内存栅栏指令?

这样做的pthread_mutex_lock调用pthread_mutex_unlock函数调用的存储栅栏/屏障指令?或者像compare_and_swap暗示那样的低级指令是否有内存障碍?

c gcc multicore pthreads

12
推荐指数
2
解决办法
5027
查看次数

编译器绕互斥边界重新排序?

假设我有自己的非内联函数LockMutex和UnlockMutex,它们正在使用一些适当的互斥体 - 例如boost - inside.对于LockMutex和UnlockMutex的调用,编译器如何知道不重新排序其他操作?它不可能知道如何在其他编译单元中实现这些功能.

void SomeClass::store(int i)
{
  LockMutex(_m);
  _field = i;  // could the compiler move this around?
  UnlockMutex(_m);
}
Run Code Online (Sandbox Code Playgroud)

ps:应该使用类的实例来保存锁以保证解锁.我把它留下来简化示例.

c++ compiler-optimization memory-barriers

7
推荐指数
1
解决办法
1533
查看次数

c++11 及更高版本中 mutex.lock() 和 .unlock() 的确切线程间重新排序约束是什么?

根据https://en.cppreference.com/w/cpp/atomic/memory_order mutex.lock()mutex.unlock()是获取和释放操作。获取操作使得无法在它前面重新排序后面的指令。并且释放操作使得在它之后无法重新排序之前的指令。这使得以下代码:

[Thread 1]
mutex1.lock();
mutex1.unlock();
mutex2.lock();
mutex2.unlock();
[Thread 2]
mutex2.lock();
mutex2.unlock();
mutex1.lock();
mutex1.unlock();
Run Code Online (Sandbox Code Playgroud)

可以重新排序为以下(可能是死锁)代码:

[Thread 1]
mutex1.lock();
mutex2.lock();
mutex1.unlock();
mutex2.unlock();
[Thread 2]
mutex2.lock();
mutex1.lock();
mutex2.unlock();
mutex1.unlock();
Run Code Online (Sandbox Code Playgroud)

这种重新排序是否可能发生。或者有什么规则阻止它?

c++ mutex memory-barriers language-lawyer c++11

7
推荐指数
1
解决办法
223
查看次数

sem_post(sem_t*sem)和sem_wait(sem_t*sem)周围是否有完整的内存屏障?

在linux代码中,我记得听说mutex_lock()周围有一个完整的内存障碍.我想确定它是否也在sem_xxx附近.

c c++ linux

4
推荐指数
2
解决办法
648
查看次数

使用平台提供的同步操作是一种UB吗?

#include <pthread.h>     
#include <thread>
int main(){
  pthread_mutex_t mut;
  if (pthread_mutex_init(&mut, NULL) != 0){
     return 0;
  }
  int a = 0; 
  auto t1 = std::thread([&](){
     for(int c = 0; c<=10000;c++){
        pthread_mutex_lock(&mut);
        a += 1;  //#1 suppose this non-atomic object is protected by the mutex
        pthread_mutex_unlock(&mut);
     }
  });
  auto t2 = std::thread([&](){
     int r = 0;
     for(;;){
        pthread_mutex_lock(&mut);
        r = a;
        std::cout<< a <<std::endl;  //#2 suppose this non-atomic object is protected by the mutex
        pthread_mutex_unlock(&mut);
        if(r>=10000){
           return;
        }
     }
  });
  t1.join();
  t2.join(); …
Run Code Online (Sandbox Code Playgroud)

c++ atomic synchronous language-lawyer c++20

2
推荐指数
1
解决办法
226
查看次数

调用库函数是否仍然会使它们成为非叶函数?x86 汇编如何处理库函数?

因此,当我们的 C 程序(或其他语言)的函数 (funcA) 调用同一程序中的另一个函数 (funcB) 时,funcA 被认为是非叶函数,因为它调用其他函数。因此,设置了堆栈框架和所有内容,而不是使用 redzone。

然而,比如说在 funcB 中,我们不会调用在程序本身中显式编写的任何函数,但我们确实调用了一两个库函数,例如 fscanf()、fopen() (但我认为这并不重要,只要它是库函数)。那么 funcB 是否会不是叶函数,因为它仍在调用另一个函数?x86 中如何处理库函数?

分析一些 x86 很明显没有发生明显的跳转,但我可以看到它的执行方式类似于,call __isoc99_fscanf@PLT #call perror@PLT #

c x86 assembly

0
推荐指数
1
解决办法
115
查看次数