代码之家  ›  专栏  ›  技术社区  ›  Brans Ds

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

  •  2
  • Brans Ds  · 技术社区  · 7 年前

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

    2 回复  |  直到 7 年前
        1
  •  4
  •   Slava    7 年前

    你可以用薄薄的RAII包装 std::atomic<> :

    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
         ...
    }
    

    这是一个简单的版本,可用于单一用途,以展示其想法,如有必要,还可以改进为用于多种功能

        2
  •  0
  •   Garrett Gutierrez    7 年前

    听起来你需要一个互斥锁。假设您正在使用 std::thread 您可以查看以下链接中的编码示例,以便专门使用 std::mutex : http://www.cplusplus.com/reference/mutex/mutex/

    // 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;
    }
    

    在上述代码中 print_block 锁定 mtx ,执行需要执行的操作,然后解锁 mtx公司 . 如果 print\u块 从两个不同的线程调用,一个线程将锁定 mtx公司 第一个线程和另一个线程将阻塞 mtx.lock() 并强制等待其他线程调用 mtx.unlock() . 这意味着只有一个线程可以在 mtx。锁定() mtx。解锁() (不包括)同时。

    这假设“在同一时间”是指在同一文字时间。如果您只希望一个线程能够调用一个函数,我建议您深入研究 std::this_thread::get_id 这将为您获取当前线程的id。断言可以简单到将所属线程存储在 owning_thread_id 然后打电话 assert(owning_thread_id == std::this_thread::get_id()) .