跨线程使用对象属性是否可行?主线程调用SetX会触发未定义行为吗?
问题解答
问题1:若对象在其他线程中被使用,该对象的属性是否仍可正常使用?
核心看线程间的操作有没有竞态冲突:
- 如果多个线程同时读写同一个属性,又没加同步机制(比如互斥锁、原子操作),肯定会出问题——属性值可能乱掉,甚至引发逻辑错误。
- 如果不同线程操作不同属性(比如示例里的
x和y这种独立的基础类型成员),只要没有线程在同时修改对象的整体状态(比如销毁对象、修改指向对象的指针),这类属性操作是安全的,能正常使用。
问题2:示例中,尽管新线程未访问x属性,但因对象本身被新线程操作,主线程调用SetX时是否会产生未定义行为甚至崩溃?
不会,原因如下:
- 内存访问无重叠:
x和y是两个独立的int成员,内存地址完全分开。新线程只对y进行读写,主线程调用SetX只修改x,两者没有对同一内存位置的并发操作,不存在竞态冲突。 - 对象指针有效:主线程先完成
obj的初始化(new Object(1,2)),再创建子线程,子线程运行期间obj始终是有效的(示例中没有提前销毁对象的逻辑),不会出现野指针访问问题。 SetX操作安全:对int类型的赋值操作在多数平台上是原子操作,而且没有其他线程干扰x的读写,完全不存在风险。
修正后的示例代码(原代码存在变量名笔误,已修正)
class Object{ public: int x; int y; Object(int x, int y) { this->x = x; this->y = y; } void SetX(int x) { this->x = x; } }*obj = nullptr; // 原代码变量名是object,与线程函数内的obj不一致,已修正 int *value_only = nullptr; void ch() { while(true) // 假设存在退出循环的机制 { // 通过obj变量操作 // 读操作 auto link = obj; auto y = obj->y; // 写操作 obj->y = 5; // 通过指针直接操作 // 读操作 auto yy = *value_only; // 写操作 *value_only = 2; // 注意:此处未操作obj->x } } int main() { obj = new Object(1,2); value_only = &obj->y; thread th(ch); obj->SetX(4); // 假设线程th的终止已妥善处理 return 0; }
内容的提问来源于stack exchange,提问作者Ngdgvcb
相关产品推荐
相关产品推荐

