Unix Programming - Meet a problem when using the signals

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > March 2007 > Meet a problem when using the signals





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Meet a problem when using the signals
Dave

2007-03-21, 7:20 pm

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 }

Jens Thoms Toerring

2007-03-21, 7:20 pm

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
Bin Chen

2007-03-22, 1: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.

Dave

2007-03-22, 1: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.

Bin Chen

2007-03-22, 1: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


Bjorn Reese

2007-03-22, 7:30 am

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
Jens Thoms Toerring

2007-03-22, 7:24 pm

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
Rainer Weikusat

2007-03-23, 7:25 am

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






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com