LinuxThreads : problem with sigwait()

LinuxThreads : problem with sigwait()

Post by Oliver Kowalk » Wed, 11 Oct 2000 04:00:00



Hi,

I'm reading "Programming with POSIX Threads" from Butenhof. I have a problem
with the function 'sigwait()'.

my program    :    creates a thread which waits on SIGINT. If SIGINT is 5
times signaled it terminates.
the problem    :    The program create 3 processes. Why? I've never called
fork()!
my system    :        Debian Linux 2.2
                            glibc 2.1.3-10

Please, can you explain me the behaviour.

thx!

with regards,
Oliver

----> sigwait.c
<---------------------------------------------------------------------------
--------------------

#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include "errors.h"

pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;
int     interrupted = 0;
sigset_t   signal_set;

/* Wait for the SIGINT signal. */
void * signal_waiter( void * arg)
{
 int sig_number;
 int signal_count = 0;
 int status;

 while ( 1)
 {
  sigwait( & signal_set, & sig_number);
  if ( sig_number == SIGINT)
  {
   printf("Got SIGINT (%d of 5)\n", signal_count + 1);
   if ( ++signal_count >= 5)
   {
    status = pthread_mutex_lock( & mutex);
    if ( status != 0)
     err_abort( status, "Lock mutex");
    interrupted = 1;
    status = pthread_cond_signal( & cond);
    if ( status != 0)
     err_abort( status, "Signal condition");
    status = pthread_mutex_unlock( & mutex);
    if ( status != 0)
     err_abort( status, "Unlock mutex");
    break;
   }
  }
  else
   printf("Got othe signal.\n");
 }
 return NULL;

Quote:}

int main( int argc, char * argv[])
{
 pthread_t  signal_thread_id;
 int    status;

 sigemptyset( & signal_set);
 sigaddset( & signal_set, SIGINT);
 status = pthread_sigmask( SIG_BLOCK, & signal_set, NULL);
 if ( status != 0)
  err_abort( status, "Set signal mask");

 /* Create the sigwait thread. */
 status = pthread_create( & signal_thread_id, NULL, signal_waiter, NULL);
 if ( status != 0)
  err_abort( status, "Create sigwaiter");

 /* Wait for the sigwait thread to receive SIGINT and signal the condition
variable. */
 status = pthread_mutex_lock( & mutex);
 if ( status != 0)
  err_abort( status, "Lock mutex");
 while( !interrupted)
 {
  status = pthread_cond_wait( & cond, & mutex);
  if ( status != 0)
   err_abort( status, "Wait for interrupt");
 }
 status = pthread_mutex_unlock( & mutex);
 if ( status != 0)
  err_abort( status, "Unlock mutex");
 printf("Main terminating with SIGINT\n");
 return 0;

Quote:}

--> errors.h
<---------------------------------------------------------------------------
---

#ifndef __ERRORS_H
#define __ERRORS_H

#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef DEBUG
#define DPRINTF( arg) printf arg
#else
#define DPRINTF( arg)
#endif

#define err_abort(code,text) \
do \
{  \
 fprintf( stderr, "%s at \"%s\":%d: %s\n", text, __FILE__, __LINE__,
strerror( code) ); \
 abort(); \

Quote:} while ( 0)

#define errno_abort(text) \
do \
{  \
 fprintf( stderr, "%s at \"%s\":%d: %s\n", text, __FILE__, __LINE__,
strerror( errno) ); \
 abort(); \

Quote:} while ( 0) \

#endif // __ERRORS_H
 
 
 

LinuxThreads : problem with sigwait()

Post by Arthur H. Gol » Fri, 13 Oct 2000 15:15:47



> Hi,

> I'm reading "Programming with POSIX Threads" from Butenhof. I have a problem
> with the function 'sigwait()'.

> my program    :    creates a thread which waits on SIGINT. If SIGINT is 5
> times signaled it terminates.
> the problem    :    The program create 3 processes. Why? I've never called
> fork()!
> my system    :        Debian Linux 2.2
>                             glibc 2.1.3-10

> Please, can you explain me the behaviour.

> thx!

> with regards,
> Oliver

Under linuxthreads, threads _are_ processes, created through
the system call clone() (of which fork is a special case),
which share the same address space (as opposed to the
copy-on-write behavior of fork).
The three processes you're seeing are the manager thread,
the initial thread and the new thread you've created using
pthread_create().

HTH,
--ag

- Show quoted text -

Quote:

> ----> sigwait.c
> <---------------------------------------------------------------------------
> --------------------

> #include <sys/types.h>
> #include <unistd.h>
> #include <pthread.h>
> #include <signal.h>
> #include "errors.h"

> pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
> pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;
> int     interrupted = 0;
> sigset_t   signal_set;

> /* Wait for the SIGINT signal. */
> void * signal_waiter( void * arg)
> {
>  int sig_number;
>  int signal_count = 0;
>  int status;

>  while ( 1)
>  {
>   sigwait( & signal_set, & sig_number);
>   if ( sig_number == SIGINT)
>   {
>    printf("Got SIGINT (%d of 5)\n", signal_count + 1);
>    if ( ++signal_count >= 5)
>    {
>     status = pthread_mutex_lock( & mutex);
>     if ( status != 0)
>      err_abort( status, "Lock mutex");
>     interrupted = 1;
>     status = pthread_cond_signal( & cond);
>     if ( status != 0)
>      err_abort( status, "Signal condition");
>     status = pthread_mutex_unlock( & mutex);
>     if ( status != 0)
>      err_abort( status, "Unlock mutex");
>     break;
>    }
>   }
>   else
>    printf("Got othe signal.\n");
>  }
>  return NULL;
> }

> int main( int argc, char * argv[])
> {
>  pthread_t  signal_thread_id;
>  int    status;

>  sigemptyset( & signal_set);
>  sigaddset( & signal_set, SIGINT);
>  status = pthread_sigmask( SIG_BLOCK, & signal_set, NULL);
>  if ( status != 0)
>   err_abort( status, "Set signal mask");

>  /* Create the sigwait thread. */
>  status = pthread_create( & signal_thread_id, NULL, signal_waiter, NULL);
>  if ( status != 0)
>   err_abort( status, "Create sigwaiter");

>  /* Wait for the sigwait thread to receive SIGINT and signal the condition
> variable. */
>  status = pthread_mutex_lock( & mutex);
>  if ( status != 0)
>   err_abort( status, "Lock mutex");
>  while( !interrupted)
>  {
>   status = pthread_cond_wait( & cond, & mutex);
>   if ( status != 0)
>    err_abort( status, "Wait for interrupt");
>  }
>  status = pthread_mutex_unlock( & mutex);
>  if ( status != 0)
>   err_abort( status, "Unlock mutex");
>  printf("Main terminating with SIGINT\n");
>  return 0;
> }

> --> errors.h
> <---------------------------------------------------------------------------
> ---

> #ifndef __ERRORS_H
> #define __ERRORS_H

> #include <unistd.h>
> #include <errno.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>

> #ifdef DEBUG
> #define DPRINTF( arg) printf arg
> #else
> #define DPRINTF( arg)
> #endif

> #define err_abort(code,text) \
> do \
> {  \
>  fprintf( stderr, "%s at \"%s\":%d: %s\n", text, __FILE__, __LINE__,
> strerror( code) ); \
>  abort(); \
> } while ( 0)
> #define errno_abort(text) \
> do \
> {  \
>  fprintf( stderr, "%s at \"%s\":%d: %s\n", text, __FILE__, __LINE__,
> strerror( errno) ); \
>  abort(); \
> } while ( 0) \

> #endif // __ERRORS_H

--
Artie Gold, Austin, TX  (finger the cs.utexas.edu account
for more info)

--
"I'd sooner fly another combat mission than ride the Cyclone
again" -- Joseph Heller