线程内对象调用类静态方法ABC::calculate()是否需加锁?
要不要给
ABC::calculate()加锁?看这两点就够了 其实答案很直接:完全取决于这个静态函数内部有没有访问或修改「跨线程共享的可变状态」——说白了就是有没有多个线程能同时碰的、可修改的数据。我给你拆成两种典型场景讲:
不需要加锁的场景
如果calculate()是个「纯函数」——也就是它的输出只由输入参数决定,内部既不访问静态成员变量、全局变量,也不调用任何线程不安全的外部函数,全程只在当前线程的栈上干活。比如这种:class ABC { public: static double calculate(double radius) { // 只是纯计算,没有任何共享数据 return 3.14159 * radius * radius; } };这种情况下,多线程同时调用完全没问题,每个线程的调用都是独立的,不会有数据竞争,根本不需要加锁。
必须加锁的场景
只要calculate()碰了任何跨线程共享的可变数据,不管是ABC的静态成员变量、全局变量,还是其他类的共享实例,而且存在「读+写」或者「多写」的情况,那必须加锁(或者用原子变量、其他同步机制)。举个例子:class ABC { private: static int request_count; // 所有线程共享的计数器 public: static int calculate(int input) { request_count++; // 多个线程同时写这个变量,会有数据竞争 return input * request_count; } }; int ABC::request_count = 0;这里
request_count是所有线程共享的,多个线程同时执行request_count++会导致计数错误(因为这个操作不是原子的),这时候就得加锁,比如用std::mutex:#include <mutex> class ABC { private: static int request_count; static std::mutex count_mutex; // 保护共享变量的锁 public: static int calculate(int input) { std::lock_guard<std::mutex> lock(count_mutex); // 自动加锁解锁 request_count++; return input * request_count; } }; int ABC::request_count = 0; std::mutex ABC::count_mutex;另外还要注意:就算只是读共享数据,如果这个数据可能被其他线程修改,那也需要同步——不然可能读到半更新的脏数据。
最后再总结一句:核心就是看有没有共享的可变状态,没有就不用锁,有就必须同步。
内容的提问来源于stack exchange,提问作者satheesh v
相关产品推荐
相关产品推荐

