gpt4 book ai didi

multithreading - 在多处理器线程中优化内存数据库的QSql

转载 作者:行者123 更新时间:2023-12-03 17:17:15 26 4
gpt4 key购买 nike

这是我的问题,我有一个 sqlite memory database通过使用 QSql .我有几个线程,每个线程处理这个公共(public)数据库的一个不同表。我使用 Win API确保这些线程在不同的处理器上工作,如下所示:

SetThreadAffinityMask (hThread, processorMask);

当只有线程处理一张表时,它需要 10 秒并使用总 CPU 的 25%。但是当有 4 个线程处理 4 个不同的表时,它需要将近 40 秒并且只使用总 CPU 的 35%。我认为原因是有某种 thread-safe在一个数据库中同步。但是由于不同的线程读取或写入不同的表,线程安全会减慢我的程序。我该如何优化它。

更新:最可能的原因是 Qt 内部的某种锁。或/和 Sqlite 3减慢我的程序,因此是否可以通过预设关闭或绕过这些锁。

更新 2:这是一个例子。 (可能有点长,抱歉)

class MultiProcessorThread
{
public:
virtual void run();
bool start()
{
m_hThread = CreateThread (NULL, 0, MultiProcessorThread::ThreadFunc, this, CREATE_SUSPENDED, NULL);

if (m_hThread != INVALID_HANDLE_VALUE)
{
RunningThreadCount++;
m_ProcessorMask = 1 << ( (RunningThreadCount - 1) % ProcessorCount);
SetThreadAffinityMask (m_hThread, m_ProcessorMask); // Make thread working on different processor
ResumeThread (m_hThread);
return true;
}
else
return false;
}
protected:
static DWORD WINAPI ThreadFunc (LPVOID in);
HANDLE m_hThread;
DWORD_PTR m_ProcessorMask;
static DWORD_PTR ProcessorCount;
static DWORD_PTR RunningThreadCount;
static DWORD_PTR GetNumCPUs();
};

DWORD_PTR MultiProcessorThread::ProcessorCount = GetNumCPUs();
DWORD_PTR MultiProcessorThread::RunningThreadCount = 0;
DWORD_PTR MultiProcessorThread::GetNumCPUs() // Get how many processors on this PC
{
SYSTEM_INFO m_si = {0};
GetSystemInfo (&m_si);
return (DWORD_PTR) m_si.dwNumberOfProcessors;
}
DWORD WINAPI MultiProcessorThread::ThreadFunc (LPVOID in)
{
static_cast<MultiProcessorThread*> (in)->run();
return 0;
}

class Run : public MultiProcessorThread
{
public:
void run()
{
int i = 0;
QString add = "insert into %1 values(1)";
add = add.arg (table);
QString sel = "select a from %1 ";
sel = sel.arg (table);
QString del = "delete from %1 where a=1";
del = del.arg (table);

while (++i) // read and write database
{
query.exec (add);
query.exec (sel);
query.exec (del);
}
}
QSqlQuery query;
QString table;
};

int main (int argc, char *argv[])
{
QCoreApplication a (argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase ("QSQLITE", "test");
db.setDatabaseName (":memory:"); // All threads working on the same memory database.
db.open();
QSqlQuery q (db), q1 (db), q2 (db);
q.exec ("create table A (a)");
q1.exec ("create table B (a)");
q2.exec ("create table C (a)"); // All threads working on different table.
Run b[3];
b[0].query = QSqlQuery (q);
b[0].table = "A";
b[1].query = QSqlQuery (q1);
b[1].table = "B";
b[2].query = QSqlQuery (q2);
b[2].table = "C";
b[0].start();
b[1].start();
b[2].start();
return a.exec();
}

最佳答案

首先,不要显式设置关联掩码,windows 会自动在最空闲的核心上分配线程。在这种情况下,依靠操作系统进行线程分发比您的代码更好。

据我所知,sqlite 在写入时会锁定整个数据库,这就是为什么您没有获得预期的性能提升。查看 sqlite 锁定文档 http://www.sqlite.org/lockingv3.html

关于multithreading - 在多处理器线程中优化内存数据库的QSql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8877435/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com