Thread: Problem with infinite loop in signal handler

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    1

    Problem with infinite loop in signal handler

    Hi all,
    I have problem with handling signals in simple program. Program starts
    one thread (only task of this thread is printing "Hello World") and
    after while sends signal to this thread (signal handler is previously
    registered). In signal handler is infinite loop that should suspend
    thread forever. But it suspends whole application. I think this
    problem is related with printf function because when I replace it with
    with linux write sys function problem does not occures. And one more
    info: problem occures not always, but most of time; maybe somewhere
    there is a race condition.
    This is whole code of application:

    Code:
    #include <signal.h>
    #include <stdio.h>
    
    void suspend(int sig) {
       printf("suspending\n");
       fflush(stdout);
       while(1);
    }
    
    
    void* loop_func(void* arg) {
       int i = 0;
       while(1) {
           if(i % 10000 == 0) {
               printf("Hello World %d\n", i);
               fflush(stdout);
           }
           i++;
       }
    }
    
    void wait_some_time() {
       int i;
       for(i = 0; i < 10000000; i++) { }
    }
    
    int main(void) {
    
       struct sigaction sa;
       pthread_t thread1;
    
       sa.sa_handler = suspend;
       sa.sa_flags = SA_RESTART;
       sigemptyset(&sa.sa_mask);
       sigaction(SIGUSR1, &sa, NULL);
    
       pthread_create(&thread1, 0, loop_func, 0);
       wait_some_time();
    
       pthread_kill(thread1, SIGUSR1);
       printf("Waiting for terminate...\n");
       wait_some_time();
    
       return 0;
    }
    Could any body tell me why this signal handler hangs whole
    application? It should hangs only one thread. It seems to be be a bug
    in linux kernel or maybe in C library. How can I solve this problem?

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    void wait_some_time() {
       int i;
       for(i = 0; i < 10000000; i++) { }
    }
    The absolute WORST way to do this. You max out the processor for nothing. Very bad thing to do. Use sleep() or if 1 second is too long, nanosleep().

    The reason the signal handler suspends the whole program is because the signal handler applies to the whole program, not just the thread. If you move the signal handler to the thread, it will work the way you want:
    Code:
    void* loop_func(void* arg) {
       struct sigaction sa; 
       int i = 0;
       sa.sa_handler = suspend;
       sa.sa_flags = SA_RESTART;
       sigemptyset(&sa.sa_mask);
       sigaction(SIGUSR1, &sa, NULL);
       while(1) {
           if(i % 10000 == 0) {
               printf("Hello World %d\n", i); 
               fflush(stdout);
           }
           i++;
       }   
    }
    [edit] Just noticed no <strike> tag...anyway I removed a comment quoted by bithub next (since s/he's right and I'm wrong) but that may seem confusing...
    Last edited by MK27; 07-22-2009 at 01:24 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    That should be void, not void*
    No, it's correct the way it is.

    Also, you cannot call printf() in a signal handler. Only asychronous-safe function calls are allowed in a signal handler.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You aren't allowed to call printf() from a signal handler, period.

    In fact, there is very little you are allowed to do from within a signal handler.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by bithub
    No, it's correct the way it is.
    hmm... but then where does loop_func return a pointer, or anything at all?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by laserlight View Post
    hmm... but then where does loop_func return a pointer, or anything at all?
    His code doesn't which is a problem. That doesn't change that fact that thread procedure functions are defined as void* (*proc)(void*)

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bithub View Post
    His code doesn't which is a problem. That doesn't change that fact that thread procedure functions are defined as void* (*proc)(void*)
    Yeah. I've barely written anything with threads but I just noticed I did use void*, so hopefully there was a good reason, since I didn't return anything either -- the threads have the same lifespan as the program. Will edit my post.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with a loop
    By wiggsfly in forum C Programming
    Replies: 5
    Last Post: 11-30-2008, 12:45 PM
  2. whats the problem....
    By vapanchamukhi in forum C Programming
    Replies: 3
    Last Post: 09-05-2008, 12:19 PM
  3. infinite loop with signal chaining
    By zxcv in forum C Programming
    Replies: 1
    Last Post: 04-18-2008, 10:14 AM
  4. using a signal handler to kill processes
    By dinjas in forum C Programming
    Replies: 2
    Last Post: 03-16-2005, 12:58 PM
  5. Infinite loop problem
    By Xanth in forum C++ Programming
    Replies: 2
    Last Post: 02-20-2005, 12:08 AM