使用Qt将所有数据库操作放在一个特定的线程中
Put all database operations in a specific thread using Qt
我有一个控制台应用程序,在超时信号之后,应该逐个元素解析2D矩阵(15*1200)并插入到数据库中。由于这个操作很耗时,所以我使用QConcurrent::run
在一个新线程中执行插入操作。
然而,由于超时信号,在一个线程结束之前可能会有多个线程启动,因此可能会发生对数据库的多次访问。作为解决方案,我试图在特定的线程中缓冲所有数据库操作,换句话说,将特定线程分配给数据库类,但不知道如何这样做。
您的问题是一个经典的并发数据分析问题。你试过使用std::mutex
吗?下面是它的用法:
你创建了一些变量std::mutex
(互斥=互斥),所有相关的线程都可以访问。
std::mutex myLock;
然后,假设处理数据的函数是这样的:
void processData(const Data& myData)
{
ProcessedData d = parseData();
insertToDatabase(d);
}
现在从我的理解,你担心多个线程会同时调用insertToDatabase(d)
。现在要解决这个问题,只需执行以下操作:
void processData(const Data& myData)
{
ProcessedData d = parseData();
myLock.lock();
insertToDatabase(d);
myLock.unlock();
}
现在,如果另一个线程试图访问同一个函数,它将阻塞,直到其他所有线程完成。所以线程相互排斥一起访问调用。
更多信息:
事项:
这个互斥对象必须与所有线程看到的互斥对象相同,否则这是无用的。所以要么让它全局(坏主意,但会工作),或者把它放在一个类,将做调用。
互斥对象是不可复制的。因此,如果在类中包含互斥对象,则应该将互斥对象设置为指针,或者重新实现该类的复制构造函数以防止复制互斥对象,或者使用
将类设置为不可复制的。delete
:class MyClass { //... stuff MyClass(const MyClass& src) = delete; //... other stuff };
使用
std::mutex
还有更花哨的方式,包括std::lock_guard
和std::unique_lock
,它们获得互斥锁的所有权并为您执行锁。如果您知道调用insertToDatabase(d);
可能会抛出异常,则可以使用此方法。在这种情况下,仅使用我编写的代码将无法解锁互斥锁,程序将达到死锁。
lock_guard
:
void processData(const Data& myData)
{
ProcessedData d = parseData();
std::lock_guard<std::mutex> guard(myLock);
insertToDatabase(d);
//it will unlock automatically at the end of this function, when the object "guard" is destroyed
}
请注意,在同一个线程中调用
lock()
两次会产生未定义行为。如果您要处理多线程,我建议您开始阅读有关多线程数据管理的内容。这是一本好书。
如果你坚持使用Qt的东西,这里是同样的东西从Qt…QMutex .
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- 在另一个线程中调用luaL_error会引发qWarning
- C++一个线程如何正确通信其任务已完成?
- 最佳做法是从另一个线程访问 qml 中的Q_PROPERTY
- C++线程:如何在一个线程仍在运行时阻止另一个线程执行 (Win32)
- 如何制作一个只能在一个线程上同时执行的函数?
- 结束另一个线程中使用的对象的生存期
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 一个线程等待多个线程事件
- 从不同进程中的另一个线程挂起/恢复线程或进程
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 计时器是否从另一个线程启动?
- 互斥,Windows 10,c ++,在一个线程上获取,在另一个线程上发布
- Qt 在另一个线程中无限循环
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 从另一个线程发出信号是否安全?
- AMQP-CPP,libev >停止ev_loop来自另一个线程