0

我的应用程序的工作方式如下:工作线程初始化并开始在 pthread_cond_wait() 中等待主线程连接到数据库并开始一次将一行移交给适当的工作人员

由于 DB-driver 内部结构,在提取当前行之前无法读取下一行,因此主线程必须等待工作线程“接受”该行。

我通过在主线程中调用 pthread_cond_wait() 来实现这一点——等待来自工作线程的 pthread_signal()。这在 Linux 和 FreeBSD 上都可以正常工作,但在 Linux 上通常需要更长的时间。虽然我在 FreeBSD 上始终在大约 27 秒内处理整个 160 万行,但在 Linux 上通常需要 2 分钟以上。除了有时Linux 框显示相同的时间...

代码是从相同的源编译的,程序与相同的数据库服务器通信。如果有的话,Linux 机器与 DB 位于同一个 LAN 上,而 FreeBSD 机器通过 VPN 连接(所以它应该会慢一点)。但是困扰我的是Linux结果的广泛不一致,我怀疑线程协调......

这是我现在拥有的:

MAIN THREAD                               WORKER
--------------------------------------------------------------------------
get new row
figure out, which worker it belongs to    lock my mutex
lock the worker's mutex                   go into pthread_cond_wait
signal the worker                         extract the row's data
unlock the worker's mutex                 signal the main thread
go into pthread_cond_wait                 unlock the mutex
go on back to getting the next row        go on to process the row's data

有没有更好的办法?谢谢!

4

2 回答 2

0

如果读取下一行无论如何都必须是串行的,那么为什么要将它委托给工作人员?由于主线程无论如何都必须等待,所以让主线程进行提取并在行被充分提取后立即进行切换,以便主线程可以继续下一行。

除此之外,您将需要提供代码,因为您的描述不完整,提交的任何此类性质的问题都不需要代码。

于 2013-01-24T01:16:32.603 回答
0

看起来您的问题是您在pthread_cond_wait()没有锁定主线程中的互斥锁的情况下调用。这意味着存在竞争条件:如果工作线程在父线程执行之前pthread_cond_wait()唤醒、提取数据并发出条件信号,则唤醒将丢失。

您应该拥有一些与条件变量配对的共享状态,如下所示:

主线:

get_new_row();
worker = decide_worker();

pthread_mutex_lock(&mutex);

/* Signal worker that data is available */
flag[worker] = 1;
pthread_cond_signal(&cond);

/* Wait for worker to extract it */
while (flag[worker] == 1)
    pthread_cond_wait(&cond, &mutex):

pthread_mutex_unlock(&mutex);

工作线程:

pthread_mutex_lock(&mutex);

/* Wait for data to be available */
while (flag[worker] == 0)
    pthread_cond_wait(&cond, &mutex):

extract_row_data();

/* Signal main thread that extraction is complete */
flag[worker] = 0;
pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);
于 2013-01-24T03:07:25.750 回答