2014-02-04 2 views
3

Я новичок в Linux. Я пытаюсь выполнить простую задачу с помощью clock_nanosleep. Проблема заключается в том, что clock_nanosleep не устанавливает errno в EINTR после прерывания сигнала. Я попытался сбросить флаг SA_RESTART. Но нет успеха. Вот мой код. Благодарю.clock_nanosleep не возвращает -1/set errno EINTR - LINUX

void signalHandler(int signum) 
{ 
    printf("Interrupt signal received.\n"); 
} 

void *periodic_thread (void *param) 
{ 
struct itimerspec its; 
struct sigevent sig; 
struct timespec next, period; 
sigset_t blocked; 

siginfo_t si; 
timer_t mytimer; 
int i, j; 

/* create a timer that will be used to periodically send a signal */ 
sig.sigev_notify = SIGEV_SIGNAL; 
sig.sigev_signo = SIGUSR1; 
sig.sigev_value.sival_ptr = &sig; 

timer_create(CLOCK_REALTIME, &sig, &mytimer); 

struct sigaction sa; 
memset(&sa, 0, sizeof(sa)); 
sa.sa_handler = &signalHandler; 
sigaction(SIGUSR1, &sa, NULL); 

/* set the periodic timer */ 
its.it_value.tv_sec = 8; 
its.it_value.tv_nsec = 00000000; 
its.it_interval.tv_sec = 0; 
its.it_interval.tv_nsec = 0; ; 
period.tv_sec = 5; 
period.tv_nsec = 00000000; 

timer_settime(mytimer, 0, &its, NULL); 

printf("periodic thread started...\n"); 

j=1; 

i = clock_gettime(CLOCK_MONOTONIC, &next); 
while(1) 
{ 
    next.tv_sec = next.tv_sec + period.tv_sec; 
    next.tv_nsec = next.tv_nsec + period.tv_nsec; 
    i = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, 0); 
    printf("I am done \n"); 
    if((i == -1) && (errno == EINTR)) 
    break; 
} 

printf("...periodic thread end!\n"); 

timer_delete(mytimer); 
return NULL; 
} 

int main() 
{ 

    pthread_t mythread; 
    pthread_attr_t myattr; 

    //struct sched_param myparam; 
    void *returnvalue; 
    sigset_t blocked; 


    /* initializes the thread attribute */ 
    pthread_attr_init(&myattr); 


    printf("starting a periodic thread...\n"); 

    pthread_create(&mythread, &myattr, periodic_thread, NULL); 

    pthread_attr_destroy(&myattr); 

    /* wait the end of the thread we just created */ 
    pthread_join(mythread, &returnvalue); 

    printf("ending main...\n"); 

return 0; 
} 

Выход >>

starting a periodic thread... 
    periodic thread started... 
    I am done 
    Interrupt signal received. 
    I am done 
    I am done 
    continues.. (Does not break the while(1)) 
+1

Уничтожение атрибутов до того, как поток обязательно имел возможность прочитать его, вероятно, не очень хорошая идея. Поменяйте операции уничтожения и соединения. Или используйте атрибуты по умолчанию (передайте нулевой указатель на 'pthread_create()'), так как вы не устанавливаете какие-либо атрибуты, не относящиеся к умолчанию. –

ответ

1

I выяснилось, что вопрос,

Проблема: Основная нить прерывалась сигналом вместо дочернего потока, состоящего из clock_nanosleep.

Раствор 1: Блок SIGUSR1 в основном потоке с использованием "pthread_sigmask (SIG_BLOCK, & блокирован, NULL)"

Решение 2: Генерация потоков конкретных событий с помощью "sigev_notify = SIGEV_THREAD_ID". (Работы для таймеров)

Thanks

0

В отличие от большинства традиционных системных вызовов, clock_nanosleep не возвращает -1 при неудаче. По the POSIX spec:

Если функция возвращает clock_nanosleep(), так как он был прерван сигналом, то он возвращает соответствующее значение ошибки.

Так что попробуйте проверить, возвращает ли он EINTR.

(Новый POSIX интерфейсы, как правило, возвращать коды ошибок вместо того, чтобы полагаться на errno. Идею чьей-то быть более современными и поточно-, я думаю. Окончательный результат просто беспорядок, хотя, ИМ.)

+0

Я уже проверил это. Вот результат: запуск периодической нити ... начата периодическая нить ... Я сделан .. Возвращаемое значение: 0 Полученный сигнал прерывания. Я закончил .. Возвращаемая стоимость: 0 I am done .. Возвращаемая стоимость: 0 I am done .. Возврат: 0 – Starscream09

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