我需要在我的简单多线程应用程序,我正在使用作为一个简单的测试平台。我想要实现的是修改传递给多个线程的一个变量的值,最后读取结果。
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
void updateValue(const std::shared_ptr<int>& value);
int main()
{
    auto sp = std::make_shared<int>(0);
    std::thread incrementThread_1(updateValue,sp);
    std::thread incrementThread_2(updateValue,sp);
    incrementThread_1.join();
    incrementThread_2.join();
    std::cout << *sp << std::endl;
}
void updateValue(const std::shared_ptr<int>& value)
{
    std::mutex g_i_mutex;
    for(int i = 0; i<100;i++)
    {
        std::unique_lock<std::mutex> lk(g_i_mutex);
        (*value)++;
        lk.unlock();
    }
}目前它只是崩溃了。我在调试窗口中没有任何有意义的信息,所以它也没有帮助。有人能告诉我我可能做错了什么吗?
要指出的一点是-我不想使用全局变量,因为函数最初位于不同的文件中。
发布于 2017-01-05 21:28:20
线程之间共享的数据需要传送自己的互斥(与完全相同的线程集共享),并要求所有访问者同意使用互斥锁来序列化访问。
一个典型的解决方案是提供一个自定义类型来封装此责任。使用这种方法,代码大致如下所示:
struct SyncInt
{
    int n = 0;
    std::mutex mx;
};
void updateValue(SyncInt & value)
{
    for (int i = 0; i != 100; ++i)
    {
        std::lock_guard<std::mutex> lock(value.mx);
        ++value.n;
    }
}
int main()
{
    SyncInt v;
    std::thread t1(updateValue, std::ref(v)), t2(updateValue, std::ref(v));
    t1.join();
    t2.join();
    std::cout << v.n << "\n";
}(请注意,示例中的共享指针对于并发性问题并不重要,因为所有代码都只使用切入点,而不是指针本身。)
发布于 2017-01-05 21:13:22
目前它只是崩溃了。有人能告诉我我可能做错了什么吗?
您正在从两个不同的线程更新共享变量value,实际上没有任何同步。这是数据竞争条件,它是未定义的行为。修复它的最简单方法是使g_i_mutex成为全局的:
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
std::mutex g_i_mutex;
void updateValue(const std::shared_ptr<int>& value);
int main()
{
    auto sp = std::make_shared<int>(0);
    std::thread incrementThread_1(updateValue,sp);
    std::thread incrementThread_2(updateValue,sp);
    incrementThread_1.join();
    incrementThread_2.join();
    std::cout << *sp << std::endl;
}
void updateValue(const std::shared_ptr<int>& value)
{
    for(int i = 0; i<100;i++)
    {
        std::unique_lock<std::mutex> lk(g_i_mutex);
        (*value)++;
        lk.unlock();
    }
}另一个没有全局变量的解决方案:
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
void updateValue(const std::shared_ptr<int>& value, std::mutex& g_i_mutex)
{
    for(int i = 0; i<100;i++)
    {
        std::unique_lock<std::mutex> lk(g_i_mutex);
        (*value)++;
        lk.unlock();
    }
}
int main()
{
    auto sp = std::make_shared<int>(0);
    std::mutex g_i_mutex;
    std::thread incrementThread_1(updateValue, sp, std::ref(g_i_mutex));
    std::thread incrementThread_2(updateValue, sp, std::ref(g_i_mutex));
    incrementThread_1.join();
    incrementThread_2.join();
    std::cout << *sp << std::endl;
}发布于 2017-01-05 20:44:08
根据这个问题的优点,根本没有必要在这个场景中使用shared_ptr。你只需要一个atomic<int>。
https://stackoverflow.com/questions/41494158
复制相似问题