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

时间:2014-12-22 21:33:15

标签: 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 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 类,每2秒创建一个新用户,并将其存储在stl列表容器用户中。

class UserDispatcher: public std::thread {
    static std::mutex mutex;
    static std::list<User> users;

    void run(void);
    void addUser(void);

public:
    UserDispatcher(void);
};

std::mutex UserDispatcher::mutex;
std::list<User> UserDispatcher::users;

void UserDispatcher::run(void) {
    std::cout << "Listener entered" << std::endl;
    while(true) {
        mutex.lock();
        std::cout << "New user" << std::endl;

        users.push_back(User(&mutex));    //Works
        addUser();                        //Don't work

        mutex.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
}

void UserDispatcher::addUser(void) {
    users.push_back(User(&mutex));
}

UserDispatcher::UserDispatcher(void)
        : std::thread(&UserDispatcher::run, this) {
}

简单的 main()功能:

int main(int argc, char **argv) {

    UserDispatcher userEngine;

    while(true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

UserDispatcher run()函数中直接创建用户时,它会起作用,但如果我只是将此行包含在 > addUser()函数程序输出已创建 0 id的所有用户。

1 个答案:

答案 0 :(得分:1)

这是问题所在:

User::User(std::mutex *mutex)
    : mutex(mutex), runUser(true), std::thread(&User::processThread, this) {
    id = nextID++;
}

std::thread(&User::processThread, this)将在执行指令id = nextID++;之前在processThread上启动新线程。

一个简单的解决方案是将线程作为User类的成员,并确保在线程之前初始化成员标识。例如,这些内容:

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)
{
}