具有shared_ptr的多线程
Multithreading with shared_ptr
我去塞我的简单多线程应用程序,我将其用作简单的测试台。我想要实现的是修改传递给多个线程的一个变量的值,并在全部完成后读取结果。
#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();
}
}
目前它只是崩溃。我在调试窗口中没有任何有意义的信息,所以它也无济于事。有人可以告诉我我可能做错了什么吗?
需要指出的一件事 - 我不想使用全局变量,因为这些函数最初位于不同的文件中。
线程之间共享的数据需要提供自己的互斥锁(与完全相同的线程集共享),并要求所有访问器同意使用该互斥锁序列化访问。
典型的解决方案是提供自定义类型来封装此责任。使用此方法,代码将大致如下所示:
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";
}
(请注意,示例中的共享指针对于有关并发性的问题并不重要,因为您的所有代码都只使用点,而从未使用指针本身。
目前它只是崩溃。有人可以告诉我我可能会做什么吗 错?
您正在从 2 个不同的线程更新共享变量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;
}
关于这个问题的优点,在这种情况下根本不需要使用shared_ptr
。您所需要的只是atomic<int>
。
您希望使用这样的数据结构,它将互斥锁与它保护访问的数据段紧密联系在一起:
class somethingShared
{
int m_value;
std::mutex m_mtx;
public:
somethingShared( int initialVal ) : m_value( initialVal ) { }
void increment()
{
std::unique_lock<std::mutex> lk(m_mtx);
++m_value;
}
int value() const { return m_value; }
};
void updateValue( somethingShared & value)
{
for ( int i = 0; i < 100; ++i )
{
value.increment();
}
}
注:注:我没有编译或运行这个,只是为了展示总体思路。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 通过安装信号处理程序关闭多线程应用程序
- 成员变量在多线程 C++ 时自行更改
- 尝试从头开始实现Leetcode的FizzBuzz多线程问题。收到"libc++abi.dylib: terminating"错误