pthreads: различное поведение при различном количестве потоков - PullRequest
2 голосов
/ 15 февраля 2011

Итак, у меня есть код (похожий на пул потоков), который создает несколько pthreads.
Сначала они блокируются мьютексом (пока все потоки не созданы), а затем ожидают условную переменную, пока основной поток не отправит им уведомление.

Я тестирую этот код на двух ПК: 1-й - gentoo x64 с 2-мя ядрами AMD, 2-й - mandriva x32 с p4 (HT включен). И я получил разные результаты.

Хорошо работает на 1-м ПК с 2 потоками в пуле и на 2 с 3 потоками в пуле.
Но!
1-й ПК с числом потоков более 2: выдает ошибку EPERM из основного потока при разблокировке мьютекса (заблокированного ранее). 2nd ПК с числом потоков более 3: выдает ошибку EINVAL из основного потока при разблокировке мьютекса (заблокированного ранее) и из всех последовательных вызовов мьютекса и cond из созданных потоков.

Есть идеи? :)

p.s. mutex и cond потоков, созданные с помощью атрибутов NULL

основной ():

...
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;
}

рутина:

<code>
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;
}
вывод на 2-й ПК с 4-мя потоками:
3076544208] hi! Im main thread!
3076544208] starting all threads
3076544208] locking...
3076544208] locked
3076544208] init:
3076544208] thread[1] = 3076541296 created
3076544208] thread[2] = 3068148592 created
3076544208] thread[3] = 3059755888 created
3076544208] thread[4] = 3051363184 created
3076544208] init done.
3076544208] unlocking...
3076544208] unlocked error=22
3051363184] run
3051363184] locking...
3051363184] locked error=22

1 Ответ

1 голос
/ 18 февраля 2011

Я поймал ошибку! Я забыл инициализировать массив threads, который является полем моего класса. ephemient был прав, это повреждение памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...