2013-05-08 2 views
2

Я думаю, что мой код не будет печатать текстВыполняет ли system() вызов типа sem_post внутри?

ну почему сюда! \ П

но это делает.

Есть что-то не так? С system()? Потому что, когда я удалил его, код работал так, как я хотел, останавливаясь.

#include <pthread.h> 
#include <semaphore.h> 
#include <stdio.h> 
#include <stdlib.h> 

pthread_t id0, id1; 
sem_t sp; 

void *fun0(void *) { 
    // When erasing the following line "system("");", 
    // it block up, and doesn't print "oh why come here!\n". 
    // But with it, it print the text! 
    system(""); 
    return NULL; 
} 

void *fun1(void *) { 
    sem_wait(&sp); 
    fprintf(stderr, "oh why come here!\n"); 
    return NULL; 
} 
int main() { 
    sem_init(&sp, 0, 0); 
    pthread_create(&id0, 0, fun0, NULL); 
    pthread_create(&id1, 0, fun1, NULL); 
    void *stat0, *stat1; 
    pthread_join(id0, &stat0); 
    pthread_join(id1, &stat1); 
    return 0; 
} 

Компилятор: GCC 4.1.2 Linux ядра: 2.6.18


Я собирал его с GCC 4.6.3, ядро ​​3.2.0, он побежал, как я хочу также. Так что я думаю, что это из-за gcc 4.1.2 или ядра 2.6.18.

ответ

1

Проблема вашего кода с sem_wait(), с sem_wait страницы человека, он говорит:.

«sem_wait() декрементах (замки) семафор указывает гипюра Если значение семафора больше нуля, то декремент продолжается, и функция возвращается немедленно. Если в семафоре в настоящее время значение равно нулю, тогда блокировка вызовов до тех пор, пока не будет возможно выполнить декремент (то есть значение семафора выше нуля) или прерыватель сигнала прерывается вызов."

В коде, который вы инициализировали с помощью sp с 0, когда sem_wait() уменьшается, он блокирует и никогда не возвращается, поскольку нет других переменных приращения потока sp.

+0

Как это может быть правильный ответ? Если sem_wait заблокирован, то следующий printf не может произойти. Случается, что поток, выполняющий систему(), запускает сигнал (вероятно, SIGCHILD?), Который прерывает sem_wait. Проверьте возвращаемое значение sem_wait, вы будете исправлены (если я прав, это -EINTR). – xryl669

+0

Вы перемещаете эти инструкции printf(), вы увидите, почему. –

3

Звонок system() не имеет к этому никакого отношения. Мои психические способности говорят мне, что sem_wait не работает с кодом ошибки, а не ждет - проверьте возвращаемое значение. Например, я могу воспроизвести ваши результаты в Mac OS X, потому что в Mac OS X sem_init() всегда терпит неудачу с ENOSYS («Функция не реализована»), что вызывает вызов sem_wait, а затем с EBADF («Плохой дескриптор файла») ,

Если добавить некоторые проверки ошибок, вы увидите, где все идет наперекосяк:

if(sem_init(&sp, 0, 0) < 0) 
    fprintf(stderr, "sem_init failed: %s\n", strerror(errno)); 
... 
if(sem_wait(&sp) < 0) 
    fprintf(stderr, "sem_wait failed: %s\n", strerror(errno)); 

Вы также должны провернуть уровень предупреждения о компилятором-я определенно рекомендую использовать -Wall и -Wextra -pedantic, если вы хотите уловить гораздо более возможные проблемы. В настоящее время ваш код вызывает неопределенное поведение, не возвращая значения из ваших fun0 и fun1 функций, которые -Wall предупредит вас. Такая ошибка может не вызвать каких-либо очевидных проблем на x86, но на других архитектурах, таких как IA64, uninitialized garbage can be deadly.

+0

Я добавляю возврат для fun0/1. Но трудно поверить, что система ("") может сделать сбой sem_wait(). –

Смежные вопросы