Meet a problem when using the signals - Unix

This is a discussion on Meet a problem when using the signals - Unix ; Hi all: I'm following the book example to use the shared memory in my project. All of the codes reference the book "UNIX SYSTEMS Programming"(chapter 15). I meet a problem which is the signal(SIGUSER1) seems doesn't work! First, I register ...

+ Reply to Thread
Results 1 to 8 of 8

Thread: Meet a problem when using the signals

  1. Meet a problem when using the signals

    Hi all:

    I'm following the book example to use the shared memory in my project.
    All of the codes reference the book "UNIX SYSTEMS Programming"(chapter
    15).
    I meet a problem which is the signal(SIGUSER1) seems doesn't work!

    First, I register a signal handler(showit) in the function
    waiting_share, this function is invoked in my GUI program(GTK) which
    want to drawing the shared memory.
    The weird thing is I send a SIGUSER1 doesn't trap the function
    "showit"!!

    I tried to arise the signal SIGUSER1 in another program and the top,
    but both of them get the same result!!

    What is the probably cause?

    thanx!!

    Dave.

    14 static void showit(int signo) {
    15 int count;
    16 double sum;
    17 if (getcountandsum() == -1){
    18 printf("Failed to get count and sum\n");
    19 }else{
    20 gdk_draw_pixbuf(virtual_LCD_pixmap,
    21 NULL,
    22 virtual_LCD_buf,
    23 0,
    24 0,
    25 0,
    26 0,
    27 -1,
    28 -1,
    29 GDK_RGB_DITHER_NORMAL,
    30 0,
    31 0);
    32
    33 }
    34 }
    35
    36 int waiting_share(gint share_key) {
    37 struct sigaction act;
    38 int key;
    39 sigset_t mask, oldmask;
    40
    41
    42 key = share_key;
    43
    44 if (initshared(key) == -1) {
    45 perror("Failed to initialize shared memory");
    46 return 1;
    47 }
    48
    49 if ((sigfillset(&mask) == -1) ||
    50 (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    51 perror("Failed to block signals to set up handlers");
    52 return 1;
    53 }
    54 printf("This is process %ld waiting for SIGUSR1 (%d)\n",
    55 (long)getpid(), SIGUSR1);
    56 act.sa_handler = showit;
    57 act.sa_flags = 0;
    58
    59 if ((sigemptyset(&act.sa_mask) == -1) ||
    60 (sigaction(SIGUSR1, &act, NULL) == -1)) {
    61 perror("Failed to set up signal handler");
    62 return 1;
    63 }
    64 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    65 perror("Failed to unblock signals");
    66 return 1;
    67 }
    68 }


  2. Re: Meet a problem when using the signals

    Dave wrote:
    > I'm following the book example to use the shared memory in my project.
    > All of the codes reference the book "UNIX SYSTEMS Programming"(chapter
    > 15).
    > I meet a problem which is the signal(SIGUSER1) seems doesn't work!


    > First, I register a signal handler(showit) in the function
    > waiting_share, this function is invoked in my GUI program(GTK) which
    > want to drawing the shared memory.
    > The weird thing is I send a SIGUSER1 doesn't trap the function
    > "showit"!!


    > I tried to arise the signal SIGUSER1 in another program and the top,
    > but both of them get the same result!!


    > What is the probably cause?


    > 14 static void showit(int signo) {
    > 15 int count;
    > 16 double sum;
    > 17 if (getcountandsum() == -1){
    > 18 printf("Failed to get count and sum\n");
    > 19 }else{
    > 20 gdk_draw_pixbuf(virtual_LCD_pixmap,
    > 21 NULL,
    > 22 virtual_LCD_buf,
    > 23 0,
    > 24 0,
    > 25 0,
    > 26 0,
    > 27 -1,
    > 28 -1,
    > 29 GDK_RGB_DITHER_NORMAL,
    > 30 0,
    > 31 0);
    > 32
    > 33 }
    > 34 }
    > 35
    > 36 int waiting_share(gint share_key) {
    > 37 struct sigaction act;
    > 38 int key;
    > 39 sigset_t mask, oldmask;
    > 40
    > 41
    > 42 key = share_key;
    > 43
    > 44 if (initshared(key) == -1) {
    > 45 perror("Failed to initialize shared memory");
    > 46 return 1;
    > 47 }
    > 48
    > 49 if ((sigfillset(&mask) == -1) ||
    > 50 (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > 51 perror("Failed to block signals to set up handlers");
    > 52 return 1;
    > 53 }
    > 54 printf("This is process %ld waiting for SIGUSR1 (%d)\n",
    > 55 (long)getpid(), SIGUSR1);
    > 56 act.sa_handler = showit;
    > 57 act.sa_flags = 0;
    > 58
    > 59 if ((sigemptyset(&act.sa_mask) == -1) ||
    > 60 (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > 61 perror("Failed to set up signal handler");
    > 62 return 1;
    > 63 }
    > 64 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > 65 perror("Failed to unblock signals");
    > 66 return 1;
    > 67 }
    > 68 }


    The part where you set up the signal handler etc. looks ok (well,
    I actually don't see why you have to block all signals but that's
    up to you). I put it in a little test program and SIGUSR1 was
    caught just fine. I don't know what you've tried but there's no-
    thing obviously wrong with what you do there. Just try it:

    #include
    #include
    #include

    static void showit(int signo) {
    printf( "Here\n" );
    }

    int main(void) {
    struct sigaction act;
    sigset_t mask, oldmask;

    if ((sigfillset(&mask) == -1) ||
    (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    perror("Failed to block signals to set up handlers");
    return 1;
    }
    act.sa_handler = showit;
    act.sa_flags = 0;
    if ((sigemptyset(&act.sa_mask) == -1) ||
    (sigaction(SIGUSR1, &act, NULL) == -1)) {
    perror("Failed to set up signal handler");
    return 1;
    }
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    perror("Failed to unblock signals");
    return 1;
    }
    pause();
    return 0;
    }

    Start it to run in the background and then send it a SIGUSR1
    signal from the command line with e.g. 'kill -USR1 '.

    What I guess the problem may be is what you try to do in the signal
    handler. Rule 1 is: don't do too many things in a signal handler.
    Rule 2 is: don't use any non-re-entrant functions. And that's what
    you do. You perhaps may use printf() in a test signal handler when
    you are sure that printf() won't be called from any other part of
    your program, but otherwise it can't be used in a signal handler.
    If your program is just in the process of doing a call of printf()
    when the signal arrives you will be in deep trouble because chances
    are that calling printf() while printf() is already being executed
    will mess up the internal data structures printf() uses. And calling
    graphics functions from a signal handler is an absolute no-no.
    Calling them involves a well-defined communication between your
    process and the X-server with a certain protocol and if you inter-
    rupt that at random moments things won't work at all. You need to
    come up with some other method to do your drawing, you definitely
    can't do that from a signal handler.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  3. Re: Meet a problem when using the signals

    On Mar 21, 8:12 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
    > Dave wrote:
    > > I'm following the book example to use the shared memory in my project.
    > > All of the codes reference the book "UNIX SYSTEMS Programming"(chapter
    > > 15).
    > > I meet a problem which is the signal(SIGUSER1) seems doesn't work!
    > > First, I register a signal handler(showit) in the function
    > > waiting_share, this function is invoked in my GUI program(GTK) which
    > > want to drawing the shared memory.
    > > The weird thing is I send a SIGUSER1 doesn't trap the function
    > > "showit"!!
    > > I tried to arise the signal SIGUSER1 in another program and the top,
    > > but both of them get the same result!!
    > > What is the probably cause?
    > > 14 static void showit(int signo) {
    > > 15 int count;
    > > 16 double sum;
    > > 17 if (getcountandsum() == -1){
    > > 18 printf("Failed to get count and sum\n");
    > > 19 }else{
    > > 20 gdk_draw_pixbuf(virtual_LCD_pixmap,
    > > 21 NULL,
    > > 22 virtual_LCD_buf,
    > > 23 0,
    > > 24 0,
    > > 25 0,
    > > 26 0,
    > > 27 -1,
    > > 28 -1,
    > > 29 GDK_RGB_DITHER_NORMAL,
    > > 30 0,
    > > 31 0);
    > > 32
    > > 33 }
    > > 34 }
    > > 35
    > > 36 int waiting_share(gint share_key) {
    > > 37 struct sigaction act;
    > > 38 int key;
    > > 39 sigset_t mask, oldmask;
    > > 40
    > > 41
    > > 42 key = share_key;
    > > 43
    > > 44 if (initshared(key) == -1) {
    > > 45 perror("Failed to initialize shared memory");
    > > 46 return 1;
    > > 47 }
    > > 48
    > > 49 if ((sigfillset(&mask) == -1) ||
    > > 50 (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > > 51 perror("Failed to block signals to set up handlers");
    > > 52 return 1;
    > > 53 }
    > > 54 printf("This is process %ld waiting for SIGUSR1 (%d)\n",
    > > 55 (long)getpid(), SIGUSR1);
    > > 56 act.sa_handler = showit;
    > > 57 act.sa_flags = 0;
    > > 58
    > > 59 if ((sigemptyset(&act.sa_mask) == -1) ||
    > > 60 (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > > 61 perror("Failed to set up signal handler");
    > > 62 return 1;
    > > 63 }
    > > 64 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > > 65 perror("Failed to unblock signals");
    > > 66 return 1;
    > > 67 }
    > > 68 }

    >
    > The part where you set up the signal handler etc. looks ok (well,
    > I actually don't see why you have to block all signals but that's
    > up to you). I put it in a little test program and SIGUSR1 was


    He only blocks all the signals during his setting up signal handler.
    This may ensure the setup process atomic.


  4. Re: Meet a problem when using the signals

    On Mar 22, 8:12 am, j...@toerring.de (Jens Thoms Toerring) wrote:
    > Dave wrote:
    > > I'm following the book example to use the shared memory in my project.
    > > All of the codes reference the book "UNIX SYSTEMS Programming"(chapter
    > > 15).
    > > I meet a problem which is the signal(SIGUSER1) seems doesn't work!
    > > First, I register a signal handler(showit) in the function
    > > waiting_share, this function is invoked in my GUI program(GTK) which
    > > want to drawing the shared memory.
    > > The weird thing is I send a SIGUSER1 doesn't trap the function
    > > "showit"!!
    > > I tried to arise the signal SIGUSER1 in another program and the top,
    > > but both of them get the same result!!
    > > What is the probably cause?
    > > 14 static void showit(int signo) {
    > > 15 int count;
    > > 16 double sum;
    > > 17 if (getcountandsum() == -1){
    > > 18 printf("Failed to get count and sum\n");
    > > 19 }else{
    > > 20 gdk_draw_pixbuf(virtual_LCD_pixmap,
    > > 21 NULL,
    > > 22 virtual_LCD_buf,
    > > 23 0,
    > > 24 0,
    > > 25 0,
    > > 26 0,
    > > 27 -1,
    > > 28 -1,
    > > 29 GDK_RGB_DITHER_NORMAL,
    > > 30 0,
    > > 31 0);
    > > 32
    > > 33 }
    > > 34 }
    > > 35
    > > 36 int waiting_share(gint share_key) {
    > > 37 struct sigaction act;
    > > 38 int key;
    > > 39 sigset_t mask, oldmask;
    > > 40
    > > 41
    > > 42 key = share_key;
    > > 43
    > > 44 if (initshared(key) == -1) {
    > > 45 perror("Failed to initialize shared memory");
    > > 46 return 1;
    > > 47 }
    > > 48
    > > 49 if ((sigfillset(&mask) == -1) ||
    > > 50 (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > > 51 perror("Failed to block signals to set up handlers");
    > > 52 return 1;
    > > 53 }
    > > 54 printf("This is process %ld waiting for SIGUSR1 (%d)\n",
    > > 55 (long)getpid(), SIGUSR1);
    > > 56 act.sa_handler = showit;
    > > 57 act.sa_flags = 0;
    > > 58
    > > 59 if ((sigemptyset(&act.sa_mask) == -1) ||
    > > 60 (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > > 61 perror("Failed to set up signal handler");
    > > 62 return 1;
    > > 63 }
    > > 64 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > > 65 perror("Failed to unblock signals");
    > > 66 return 1;
    > > 67 }
    > > 68 }

    >
    > The part where you set up the signal handler etc. looks ok (well,
    > I actually don't see why you have to block all signals but that's
    > up to you). I put it in a little test program and SIGUSR1 was
    > caught just fine. I don't know what you've tried but there's no-
    > thing obviously wrong with what you do there. Just try it:
    >
    > #include
    > #include
    > #include
    >
    > static void showit(int signo) {
    > printf( "Here\n" );
    >
    > }
    >
    > int main(void) {
    > struct sigaction act;
    > sigset_t mask, oldmask;
    >
    > if ((sigfillset(&mask) == -1) ||
    > (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > perror("Failed to block signals to set up handlers");
    > return 1;
    > }
    > act.sa_handler = showit;
    > act.sa_flags = 0;
    > if ((sigemptyset(&act.sa_mask) == -1) ||
    > (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > perror("Failed to set up signal handler");
    > return 1;
    > }
    > if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > perror("Failed to unblock signals");
    > return 1;
    > }
    > pause();
    > return 0;
    >
    > }
    >
    > Start it to run in the background and then send it a SIGUSR1
    > signal from the command line with e.g. 'kill -USR1 '.
    >

    Thank you!!
    The kill -USR1 really works fine!

    But, how could I implement the same thing in my program. I mean, I
    want to send the SIGUSER1 to another process. How to make it?

    thanx.

    Dave.


  5. Re: Meet a problem when using the signals

    On 3月22日, 下午12时09分, "Dave" wrote:
    > On Mar 22, 8:12 am, j...@toerring.de (Jens Thoms Toerring) wrote:
    >
    > > Dave wrote:
    > > > I'm following the book example to use the shared memory in my project.
    > > > All of the codes reference the book "UNIX SYSTEMS Programming"(chapter
    > > > 15).
    > > > I meet a problem which is the signal(SIGUSER1) seems doesn't work!
    > > > First, I register a signal handler(showit) in the function
    > > > waiting_share, this function is invoked in my GUI program(GTK) which
    > > > want to drawing the shared memory.
    > > > The weird thing is I send a SIGUSER1 doesn't trap the function
    > > > "showit"!!
    > > > I tried to arise the signal SIGUSER1 in another program and the top,
    > > > but both of them get the same result!!
    > > > What is the probably cause?
    > > > 14 static void showit(int signo) {
    > > > 15 int count;
    > > > 16 double sum;
    > > > 17 if (getcountandsum() == -1){
    > > > 18 printf("Failed to get count and sum\n");
    > > > 19 }else{
    > > > 20 gdk_draw_pixbuf(virtual_LCD_pixmap,
    > > > 21 NULL,
    > > > 22 virtual_LCD_buf,
    > > > 23 0,
    > > > 24 0,
    > > > 25 0,
    > > > 26 0,
    > > > 27 -1,
    > > > 28 -1,
    > > > 29 GDK_RGB_DITHER_NORMAL,
    > > > 30 0,
    > > > 31 0);
    > > > 32
    > > > 33 }
    > > > 34 }
    > > > 35
    > > > 36 int waiting_share(gint share_key) {
    > > > 37 struct sigaction act;
    > > > 38 int key;
    > > > 39 sigset_t mask, oldmask;
    > > > 40
    > > > 41
    > > > 42 key = share_key;
    > > > 43
    > > > 44 if (initshared(key) == -1) {
    > > > 45 perror("Failed to initialize shared memory");
    > > > 46 return 1;
    > > > 47 }
    > > > 48
    > > > 49 if ((sigfillset(&mask) == -1) ||
    > > > 50 (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > > > 51 perror("Failed to block signals to set up handlers");
    > > > 52 return 1;
    > > > 53 }
    > > > 54 printf("This is process %ld waiting for SIGUSR1 (%d)\n",
    > > > 55 (long)getpid(), SIGUSR1);
    > > > 56 act.sa_handler = showit;
    > > > 57 act.sa_flags = 0;
    > > > 58
    > > > 59 if ((sigemptyset(&act.sa_mask) == -1) ||
    > > > 60 (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > > > 61 perror("Failed to set up signal handler");
    > > > 62 return 1;
    > > > 63 }
    > > > 64 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > > > 65 perror("Failed to unblock signals");
    > > > 66 return 1;
    > > > 67 }
    > > > 68 }

    >
    > > The part where you set up the signal handler etc. looks ok (well,
    > > I actually don't see why you have to block all signals but that's
    > > up to you). I put it in a little test program and SIGUSR1 was
    > > caught just fine. I don't know what you've tried but there's no-
    > > thing obviously wrong with what you do there. Just try it:

    >
    > > #include
    > > #include
    > > #include

    >
    > > static void showit(int signo) {
    > > printf( "Here\n" );

    >
    > > }

    >
    > > int main(void) {
    > > struct sigaction act;
    > > sigset_t mask, oldmask;

    >
    > > if ((sigfillset(&mask) == -1) ||
    > > (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)) {
    > > perror("Failed to block signals to set up handlers");
    > > return 1;
    > > }
    > > act.sa_handler = showit;
    > > act.sa_flags = 0;
    > > if ((sigemptyset(&act.sa_mask) == -1) ||
    > > (sigaction(SIGUSR1, &act, NULL) == -1)) {
    > > perror("Failed to set up signal handler");
    > > return 1;
    > > }
    > > if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
    > > perror("Failed to unblock signals");
    > > return 1;
    > > }
    > > pause();
    > > return 0;

    >
    > > }

    >
    > > Start it to run in the background and then send it a SIGUSR1
    > > signal from the command line with e.g. 'kill -USR1 '.

    >
    > Thank you!!
    > The kill -USR1 really works fine!
    >
    > But, how could I implement the same thing in my program. I mean, I
    > want to send the SIGUSER1 to another process. How to make it?

    man 3 kill



  6. Re: Meet a problem when using the signals

    Dave wrote:

    > But, how could I implement the same thing in my program. I mean, I
    > want to send the SIGUSER1 to another process. How to make it?


    You can use the kill() system call.

    However, you seem to have ignored a very important piece of advice from
    Jens, namely that you cannot call graphics functions from a signal
    handler. It may appear to work now, and indeed it may work most of the
    time, but occasionally it will fail non-deterministically, and this can
    be very difficult to find (except, Jens has already pointed it out to
    you).

    There are two ways that you can avoid this problem. First, you can set
    a global sig_atomic_t variable from the signal handler, and then check
    for this variable outside the signal handler (e.g. in your main loop),
    and show the graphics from there. Second, you can use another IPC
    mechanism (named pipe, socket, etc.) instead of signals to communicate
    between your processes.

    --
    mail1dotstofanetdotdk

  7. Re: Meet a problem when using the signals

    Bin Chen wrote:
    > On Mar 21, 8:12 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
    > > The part where you set up the signal handler etc. looks ok (well,
    > > I actually don't see why you have to block all signals but that's
    > > up to you). I put it in a little test program and SIGUSR1 was


    > He only blocks all the signals during his setting up signal handler.
    > This may ensure the setup process atomic.


    No, there's nothing "atomic" about the setup process just because
    all signal are blocked - atomic would mean that the process can't
    be interrupted in any way during that type, especially not by get-
    ting put to sleep because its time slice is over (that would re-
    quire disabling all interrupts). Blocking all signals just makes
    sure that no signals get delivered during the installation proce-
    dure - and I fail to see what that would be necessary (or good)
    for.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  8. Re: Meet a problem when using the signals

    jt@toerring.de (Jens Thoms Toerring) writes:
    > Bin Chen wrote:


    [...]

    >> He only blocks all the signals during his setting up signal handler.

    >

    [...]

    > Blocking all signals just makes sure that no signals get delivered
    > during the installation procedure - and I fail to see what that
    > would be necessary (or good) for.


    "Peace of mind". Presumably, the underlying belief is that
    something like a partially stored function pointer can
    exist and that the kernel does not serialize signal delivery
    and signal handler setup. Both of which are most likely wrong.

+ Reply to Thread