Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多线程程序中的变量值已损坏_C++_Multithreading - Fatal编程技术网

C++ 多线程程序中的变量值已损坏

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

嗯。我有点误解了互斥体的概念。但我仍然有一个奇怪的问题。我简化了一个代码,没有使用任何奇特的库,现在它应该每2秒创建一个新用户:

下面是用户类,它什么也不做,只显示启动时间及其id:

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的构造函数。@omicrons
processThread()
在它自己的线程中运行,不要等待互斥锁。这是对那些没有完全复制这个答案中模式的人的警告。初始化器列表中的初始化顺序将按照声明成员变量的顺序进行。也就是说,在某些情况下,
此线程
仍然可以在没有
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)
{
}