【发布时间】:2011-02-15 19:15:05
【问题描述】:
所以,我有一个创建少量 pthread 的代码(类似线程池)。
它们首先被互斥体阻塞(而所有线程都没有创建),然后等待条件变量,直到主线程向它们广播通知。
我在两台 PC 上测试此代码:1st - gentoo x64 与 2 核 AMD,2nd - mandriva x32 与 p4(HT 开启)。我得到了不同的结果。
它在池中有 2 个线程的 1st PC 上运行良好,在池中有 3 个线程的 2nd 上运行良好。
但是!
1st 线程数超过 2 的 PC:在解锁互斥锁(之前锁定)时从主线程抛出错误 EPERM。
2nd 线程数超过 3 的 PC:在解锁互斥锁(之前锁定)以及从创建的线程对 mutex 和 cond 的所有顺序调用时从主线程抛出错误 EINVAL。
有什么想法吗? :)
附言使用 NULL attrs 创建的线程 mutex 和 cond
main():
...
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&queue_condition, NULL);
running = true;
lock();
while(pool_size<limit) {
pthread_create(&threads[pool_size++], NULL, &run, this)
}
unlock();
sleep(2);
schedule(new SimpleJob(...));
sleep(2);
...
运行():
while (running) {
lock();
Job* job = next();
if (job == NULL) {
wait();
unlock();
continue;
}
unlock();
job->execute();
delete job;
}
例程:
void lock() {
pthread_mutex_lock(&mutex);
}
void unlock() {
pthread_mutex_unlock(&mutex);
}
void wait() {
pthread_cond_wait(&queue_condition, &mutex);
}
void notifyAll() {
pthread_cond_broadcast(&queue_condition);
}
void schedule(Job* job) {
lock();
job_queue.push(job);
notifyAll();
unlock();
}
Job* next() {
if (job_queue.empty()) {
return NULL;
}
Job* job = job_queue.front();
job_queue.pop();
return job;
}
在具有 4 个线程的第二台 PC 上输出:
3076544208]嗨!我是主线!
3076544208] 启动所有线程
3076544208] 锁定...
3076544208] 锁定
3076544208] 初始化:
3076544208] 线程 [1] = 3076541296 创建
3076544208] 线程 [2] = 3068148592 创建
3076544208] 线程 [3] = 3059755888 创建
3076544208] 线程 [4] = 3051363184 创建
3076544208] 初始化完成。
3076544208] 解锁...
3076544208] 解锁错误=22
3051363184]运行
3051363184] 锁定...
3051363184] 锁定错误=22
【问题讨论】:
-
闻起来像内存损坏。使用Valgrind 运行。
-
你的意思是第二台电脑?感谢您的链接:)
-
你有一个逻辑错误、竞争条件或一些内存损坏 - 或某处 3 的组合。
-
@ydroneaud 代码附加到主题
标签: linux multithreading pthreads