C++ 多线程程序中的变量值已损坏
嗯。我有点误解了互斥体的概念。但我仍然有一个奇怪的问题。我简化了一个代码,没有使用任何奇特的库,现在它应该每2秒创建一个新用户: 下面是用户类,它什么也不做,只显示启动时间及其id:C++ 多线程程序中的变量值已损坏,c++,multithreading,C++,Multithreading,嗯。我有点误解了互斥体的概念。但我仍然有一个奇怪的问题。我简化了一个代码,没有使用任何奇特的库,现在它应该每2秒创建一个新用户: 下面是用户类,它什么也不做,只显示启动时间及其id: class User: public std::thread { static int nextID; std::mutex *mutex; int id; void run(void); public: User(std::mutex *mutex); }; int
class User: public std::thread {
static int nextID;
std::mutex *mutex;
int id;
void run(void);
public:
User(std::mutex *mutex);
};
int User::nextID = 0;
void User::run(void) {
mutex->lock();
std::cout << "User thread entered, id: " << id << std::endl;
mutex->unlock();
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
User::User(std::mutex *mutex)
: mutex(mutex), id(nextID++), std::thread(&User::run, this) {
}
当直接在UserDispatcher的run()函数中创建User时,它可以工作,但是如果我简单地将这一行括在addUser()函数中,程序输出它已经创建了所有id为0的用户。这就是问题所在:
User::User(std::mutex *mutex)
: mutex(mutex), runUser(true), std::thread(&User::processThread, this) {
id = nextID++;
}
std::thread(&User::processThread,this)
将在指令id=nextID++之前启动processThread上的新线程代码>被执行
一个简单的解决方案是将线程作为用户类的成员,并确保在线程之前初始化成员id。例如,沿着以下思路:
class User: {
static int nextID;
int id;
std::mutex *mutex;
bool runUser;
std::thread this_thread;
// ...
};
User::User(std::mutex *mutex)
: id(nextID++), mutex(mutex), runUser(true), this_thread(&User::processThread, this)
{
}
不要使用指向互斥体的指针,只使用互斥体,即std::mutex mutex
在类用户
@Basile中,但OP只需要一个互斥锁。指向互斥体的指针对我来说很好。你的代码很长。你能把它缩短吗?如果你想为用户创建一个全局互斥体,就把它声明为静态std::mutex globmutex
在类User
@Basile中,该对象已作为UserListener::mutex
存在。所有User::mutex
指针都指向它。也许我误解了什么,但我将创建新用户对象放在了mutex锁定的代码部分中,那么为什么这个线程开始运行?@omicrons,因为线程的工作函数没有自己的锁User::process
有,但是User::processThread
没有,所以cout
不在锁内。我的意思是在listen()内锁,因为它调用addUser(),后者调用User的构造函数。@omicronsprocessThread()
在它自己的线程中运行,不要等待互斥锁。这是对那些没有完全复制这个答案中模式的人的警告。初始化器列表中的初始化顺序将按照声明成员变量的顺序进行。也就是说,在某些情况下,此线程
仍然可以在没有id(nextID++)
的情况下启动,如果您对其声明的排序与此处显示的不同。
User::User(std::mutex *mutex)
: mutex(mutex), runUser(true), std::thread(&User::processThread, this) {
id = nextID++;
}
class User: {
static int nextID;
int id;
std::mutex *mutex;
bool runUser;
std::thread this_thread;
// ...
};
User::User(std::mutex *mutex)
: id(nextID++), mutex(mutex), runUser(true), this_thread(&User::processThread, this)
{
}