C++ 优雅的断言函数不是从多个线程调用的

C++ 优雅的断言函数不是从多个线程调用的,c++,multithreading,openmp,C++,Multithreading,Openmp,我有一个函数不能同时从多个线程调用。你能为这个建议一些优雅的断言吗 听起来你需要一个互斥锁。假设您使用的是std::thread,您可以查看以下链接中的编码示例,了解如何专门使用std::mutex: 在上面的代码中,print_块锁定mtx,执行它需要执行的操作,然后解锁mtx。如果从两个不同的线程调用print_block,一个线程将首先锁定mtx,另一个线程将在mtx.lock上阻塞,并强制等待,直到另一个线程调用mtx.unlock。这意味着只有一个线程可以同时执行mtx.lock和mt

我有一个函数不能同时从多个线程调用。你能为这个建议一些优雅的断言吗

听起来你需要一个互斥锁。假设您使用的是std::thread,您可以查看以下链接中的编码示例,了解如何专门使用std::mutex:

在上面的代码中,print_块锁定mtx,执行它需要执行的操作,然后解锁mtx。如果从两个不同的线程调用print_block,一个线程将首先锁定mtx,另一个线程将在mtx.lock上阻塞,并强制等待,直到另一个线程调用mtx.unlock。这意味着只有一个线程可以同时执行mtx.lock和mtx.unlock exclusive之间的代码


这假设在同一时间你的意思是在同一文字时间。如果您只希望一个线程能够调用函数,我建议您查看std::this_thread::get_id,它将为您获取当前线程的id。断言可以简单到将所属线程存储在owning_thread_id中,然后调用assertowning_thread_id==std::this_thread::get_id。

您可以在std::atomic周围使用一个精简的RAII包装器:


它是一个简单的版本,可以一次使用来展示这个想法,必要时可以改进为用于多个功能

一个人认为优雅的东西完全是基于观点的。std::mutex with try_lock你想声明它是什么意思?不同时从多个线程调用它是什么意思?您的意思是在同一时间,还是说无论何时,只有一个线程调用该函数?如果是前者,则应使用某种锁/互斥锁。如果是后者,您可以只检查调用函数的线程的id,或者如果可能,只将函数放在一个线程的范围内。这听起来像是试图围绕设计错误进行编码。函数不打算从多个线程使用,但可能会意外使用,因为环境是高度并行的。我不需要锁。这应该是一个检查或联系,它不应该从多个线程中使用。@BRANDS要可靠地检查多线程访问,您必须使用线程原语,互斥体或Atomic。我假设你指的是我在作品中解释你的问题的前一个意思。我在案例中编辑了后一个解释,这似乎是你想问的。希望这有帮助。OP不希望同时访问,OP希望确保这不会发生。您的互斥体解决方案没有解决这个问题。我喜欢线程id的想法,但是请注意,您需要保护互斥体对拥有线程id的读写。否则,将出现数据竞争。甚至可能在构造函数内部断言。我还将使计数器成为结构的静态成员,以防止修补。唯一的缺点是,这将给使用该函数的顺序代码带来开销。但它可以很容易地转换为基于策略的设计,并将不做任何事情的策略定义为默认策略。
// mutex example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex

std::mutex mtx;           // mutex for critical section

void print_block (int n, char c) {
  // critical section (exclusive access to std::cout signaled by locking mtx):
  mtx.lock();
  for (int i=0; i<n; ++i) { std::cout << c; }
  std::cout << '\n';
  mtx.unlock();
}

int main ()
{
  std::thread th1 (print_block,50,'*');
  std::thread th2 (print_block,50,'$');

  th1.join();
  th2.join();

  return 0;
}
namespace {
    std::atomic<int> access_counter;

    struct access_checker {
        access_checker() { check = ++access_counter; }
        access_checker( const access_checker & ) = delete;
        ~access_checker() { --access_counter; }
        int check;
    };
}


void foobar()
{
     access_checker checker;
     // assert than checker.check == 1 and react accordingly
     ...
}