Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7006375
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T21:28:09+00:00 2026-05-27T21:28:09+00:00

After a fork call, i have one father that must send sigusr1 or sigusr2

  • 0

After a fork call, i have one father that must send sigusr1 or sigusr2 (based on the value of the ‘cod’ variable) to his child. The child have to install the proper handlers before receiving sigusr1 or sigusr2. For doing so, i pause the father waiting for the child to signal him telling that he’s done with the handler installation. The father is signaled by sigusr1 and the handler for this signal is installed before the fork call. However, it seems the father can’t return from pause making me think that he actually never call the sigusr1 handler.

[...]

    typedef enum{FALSE, TRUE} boolean;

    boolean sigusr1setted = FALSE;
    boolean sigusr2setted = FALSE;


    void
    sigusr1_handler0(int signo){
             return;
    }

    void
    sigusr1_handler(int signo){
            sigusr1setted = TRUE;
    }

    void
    sigusr2_handler(int signo){
            sigusr2setted = TRUE;
    }  

    int main(int argc, char *argv[]){
         [...]

         if(signal(SIGUSR1, sigusr1_handler0) == SIG_ERR){
            perror("signal 0 error");
            exit(EXIT_FAILURE); 
         }

         pid = fork();
                    if (pid == 0){
                        if(signal(SIGUSR1, sigusr1_handler) == SIG_ERR){
                            perror("signal 1 error");
                            exit(EXIT_FAILURE);
                        }

                        if(signal(SIGUSR2, sigusr2_handler) == SIG_ERR){
                            perror("signal 2 error");
                            exit(EXIT_FAILURE);         
                        }

                        kill(SIGUSR1, getppid()); // wake up parent by signaling him with sigusr1

                        // Wait for the parent to send the signals...
                        pause();

                        if(sigusr1setted){
                            if(execl("Prog1", "Prog1", (char*)0) < 0){
                                perror("exec P1 error");
                                exit(EXIT_FAILURE);
                            }
                        }

                        if(sigusr2setted){
                            if(execl("Prog2", "Prog2", (char*)0) < 0){
                                perror("exec P2 error");
                                exit(EXIT_FAILURE);
                            }
                        }

                        // Should'nt reach this point : something went wrong...
                        exit(EXIT_FAILURE);

                    }else if (pid > 0){
                        // The father must wake only after the child has done with the handlers installation

                        pause(); 

                        // Never reaches this point ... 
                        if (cod == 1)
                            kill(SIGUSR1, pid);
                        else 
                            kill(SIGUSR2, pid);

                        // Wait for the child to complete..
                        if(wait(NULL) == -1){
                            perror("wait 2 error"); 
                            exit(EXIT_FAILURE);             
                        }

                             [...]

                    }else{
                        perror("fork 2 error");
                        exit(EXIT_FAILURE);
                    }
         [...]

         exit(EXIT_SUCCESS);
    }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T21:28:10+00:00Added an answer on May 27, 2026 at 9:28 pm

    Assembling a plausible answer from the comments – so this is Community Wiki from the outset. (If Oli provides an answer, up-vote that instead of this!)

    Oli Charlesworth gave what is probably the core of the problem:

    • I suspect you have produced a race condition in the opposite direction to what you anticipated. The child sent SIGUSR1 to the parent before the parent reached the pause().

    ouah noted accurately:

    • An object shared between the signal handler and the non-handler code (your boolean objects) must have a volatile sig_atomic_t type otherwise the code is undefined.

    That said, POSIX allows a little more laxity than standard C does for what can be done inside a signal handler. We might also note the C99 provides <stdbool.h> to define the bool type.

    The original poster commented:

    I don’t see how can I make sure that the parent goes in the pause() call first without using sleep() in the child (which guarantees nothing). Any ideas?

    Suggestion: Use usleep() (µ-sleep, or sleep in microseconds), or nanosleep() (sleep in nanoseconds)?

    Or use a different synchronization mechanism, such as:

    1. parent process creates FIFO;
    2. fork();
    3. child opens FIFO for writing (blocking until there is a reader);
    4. parent opens FIFO for reading (blocking until there is a writer);
    5. when unblocked because the open() calls return, both processes simply close the FIFO;
    6. the parent removes the FIFO.

    Note that there is no data communication between the two processes via the FIFO; the code is simply relying on the kernel to block the processes until there is a reader and a writer, so both processes are ready to go.

    Another possibility, is that the parent process could try if (siguser1setted == FALSE) pause(); to reduce the window for the race condition. However, it only reduces the window; it does not guarantee that the race condition cannot occur. That is, Murphy’s Law applies and the signal could arrive between the time the test is complete and the time the pause() is executed.

    All of this goes to show that signals are not a very good IPC mechanism. They can be used for IPC, but they should seldom actually be used for synchronization.

    Incidentally, there’s no need to test the return value of any of the exec*() family of functions. If the system call returns, it failed.

    And the questioner asked again:

    Wouldn’t it be better to use POSIX semaphores shared between processes?

    Semaphores would certainly be another valid mechanism for synchronizing the two processes. Since I’d certainly have to look at the manual pages for semaphores whereas I can remember how to use FIFOs without looking, I’m not sure that I’d actually use them, but creating and removing a FIFO has its own set of issues so it is not clear that it is in any way ‘better’ (or ‘worse’); just different. It’s mkfifo(), open(), close(), unlink() for FIFOs versus sem_open() (or sem_init()), sem_post(), sem_wait(), sem_close(), and maybe sem_unlink() (or sem_destroy()) for semaphores. You might want to think about registering a ‘FIFO removal’ or ‘semaphore cleanup’ function with atexit() to make sure the FIFO or semaphore is destroyed under as many circumstances as possible. However, that’s probably OTT for a test program.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a program that depends on an external shared library, but after a
I have overloaded the fork() system call and created my own version of fork()
After calling fork , the current process will call exit(0) . But the child
After being told by at least 10 people on SO that version control was
After lots of attempts and search I have never found a satisfactory way to
After hours of debugging, it appears to me that in FireFox, the innerHTML of
After I was convinced that labeled breaks/continues are a total nono over here ,
I have written a logging application in Python that is meant to start at
I have the following situation (pseudocode): function f: pid = fork() if pid ==
In perl, after fork() ing I can redirect a child's stdout to a file

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.