Meet a problem when using the signals
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Meet a problem when using the signals




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Meet a problem when using the signals  
Dave


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 12:20 AM

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 }






[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Jens Thoms Toerring


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 12:20 AM

Dave <dave.tw@gmail.com> 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 <stdio.h>
#include <signal.h>
#include <unistd.h>

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 <pid>'.

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





[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Bin Chen


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 06:24 AM

On Mar 21, 8:12 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Dave <dave...@gmail.com> 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.






[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Dave


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 06:24 AM

On Mar 22, 8:12 am, j...@toerring.de (Jens Thoms Toerring) wrote:
> Dave <dave...@gmail.com> 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
> 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 <stdio.h>
> #include <signal.h>
> #include <unistd.h>
>
> 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 <pid>'.
>
Thank you!!
The kill -USR1 <pid> 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.






[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Bin Chen


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 06:24 AM

On 3=D4=C222=C8=D5, =CF=C2=CE=E712=CA=B109=B7=D6, "Dave" <dave...@gmail.com=
> wrote:
> On Mar 22, 8:12 am, j...@toerring.de (Jens Thoms Toerring) wrote:
> 
> 
> 
> 
> 
> 
> 
> 
> 
>
> Thank you!!
> The kill -USR1 <pid> 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







[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Bjorn Reese


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-22-07 12:30 PM

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





[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Jens Thoms Toerring


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-23-07 12:24 AM

Bin Chen <binary.chen@gmail.com> wrote:
> On Mar 21, 8:12 pm, j...@toerring.de (Jens Thoms Toerring) wrote: 
[vbcol=seagreen]
> 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





[ Post a follow-up to this message ]



    Re: Meet a problem when using the signals  
Rainer Weikusat


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
03-23-07 12:25 PM

jt@toerring.de (Jens Thoms Toerring) writes:
> Bin Chen <binary.chen@gmail.com> wrote:

[...]
 
>
[...]

> 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.





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 07:07 AM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register