C++ i obsługa sygnałów w czasie drukowania

0

Witam, mam program, który powinien zawiesić jeden wątek. Natomiast dzieje się tak, że zawiesza się cała aplikacja. Kod tego programiku:

#include <iostream>
#include <sstream>
#include <signal.h>
#include <cerrno>
#include <cstdio>

void suspend(int sig) {
    sigset_t mask;

    sigfillset(&mask);
    sigdelset(&mask, SIGUSR2);
    std::cout << "suspending" << std::endl;
    while(1);
}


void* loopFunc(void*) {
    int i = 0;
    while(1) {
        if(i % 10000 == 0) {
            printf("Hello World%d\n", i);
        }
        i++;
    }
}

void waitSomeTime() {
    for(int i = 0; i < 10000000; i++) { }
}

int main(void) {

    struct sigaction sa;
    sa.sa_handler = suspend;
    sa.sa_flags = SA_RESTART;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGUSR1, &sa, NULL);


    pthread_t thread1;
    pthread_create(&thread1, 0, loopFunc, 0);
    waitSomeTime();
    pthread_kill(thread1, SIGUSR1);
    std::cout << "Waiting for terminate..." << std::endl;
    waitSomeTime();
    return 0;
}

Handler sygnału wykonuje pętle while(1) tak więc nigdy nie wróci z obsługi sygnału. Więc wątek thread1 powinien zostać zawieszony. Natomiast dzieje się coś innego. Wiesza się cała aplikacja, nawet nie zostaje wypisana linijka: Waiting for terminate...
Gdy w wątku thread1 usune wypisywanie Hello Worlda to aplikacja nie zawiesza sie. Jak dam linuksowego write zamiast std::cout to aplikacja też się nie zawiesza... Czy ktoś może wytłumaczyć dlaczego tak się dzieje?
Czy u Was na linuksie też takie coś występuje? Już zaczynam się zastanawiać czy kernel przypadkiem nie nawala...

0

Czy mógłby chociaż ktoś sprawdzić na swoim Linuksie czy program mu się wiesza? To dla mnie ważne. Gdyby u innych nie występował ten błąd to pewnie mam jakiegoś złego liba albo coś z kernelem.

0

Program wyświetla wiele razy napis Hello World, potem "suspending" i aplikacja zawiesza się.

0

Dzięki wielkie; możesz jeszcze mi powiedzieć jakiego masz kernela i jakie distro?

0

Gentoo Linux. Kernel: 2.6.30-gentoo-r2.

//EDIT

Wcześniej nie miałem czasu się bliżej temu przyjrzeć, ale teraz już chyba wiem dlaczego program się zawieszał. Problemem jest funkcja waitSomeTime(). Powoduje ona zużycie procesora 100% i za długo trwa. Uruchom to i napisz czy działa:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cerrno>
#include <cstdio>

void suspend(int sig) {
    sigset_t mask;

    sigfillset(&mask);
    sigdelset(&mask, SIGUSR2);
    std::cout << "suspending" << std::endl;
    while(1);
}


void* loopFunc(void*) {
    int i = 0;
    while(1) {
        if(i % 10000 == 0) {
            printf("Hello World%d\n", i);
        }
        i++;
    }
}

void waitSomeTime() {
    //for(int i = 0; i < 10000000; i++) { }
    sleep(3);
}

int main(void) {

    struct sigaction sa;
    sa.sa_handler = suspend;
    sa.sa_flags = SA_RESTART;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGUSR1, &sa, NULL);


    pthread_t thread1;
    pthread_create(&thread1, 0, loopFunc, 0);
    waitSomeTime();
    pthread_kill(thread1, SIGUSR1);
    std::cout << "Waiting for terminate..." << std::endl;
    waitSomeTime();
    return 0;
}
0

Ja mam zupelnie inną wersję jądra (2.6.24-21) i problem występuje tak więc pewnie to nie wina jądra...
A sleep(3) zamiast petli niestety nie pomógł. Zauważyłem jeszcze dlaczego główny wątek się zawiesza - po tym występuje instrukcja cout, gdy ją się usunie to program normalnie się kończy. Wniosek z tego, że wystąpienie sygnału w jakiś sposób masakruje strumień. I rzeczywiście zamiast zwykłego cout dałem cerr << "Waiting for terminate"; i program zakończył się poprawnie. Próbowałem też wszelkie cout zmienić na printf ale efekt ten sam. Widocznie jakoś stdout się psuje. A właściwie nie psuje tylko zawiesza się na jakiejś blokującej operacji i gdy przychodzi sygnał w czasie trwania printfa, ten już się nie odwiesza.
Aż dziwne że tak krótki program tyle zamieszania robi...
Może ktoś wie jak obejść takie zachowanie?

0

muteksy

0

winterfresh - muteksy tu nie pomogą, bo sygnał przychodzi asynchronicznie, także przy założonym muteksie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1