LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-21-2002, 05:10 AM   #1
souvik
LQ Newbie
 
Registered: Apr 2001
Location: Calcutta, India
Posts: 16

Rep: Reputation: 0
Signal handling in Multithreaded program


I have a multithreaded program and a signal handler for a user defined Signal

How can I come to know within the signal handler which thread has raised the signal

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>

#define mySig 41

void mySigHandle(int i)
{
printf("Hi");
}

/* function to be executed by the new thread */
void* do_loop(void* data)
{
int i; /* counter, to print numbers */
int j; /* counter, for delay */
int me = *((int*)data); /* thread identifying number */
kill(getpid(), mySig);

for (i=0; i<10; i++) {
for (j=0; j<500000; j++) /* delay loop */
;
printf("'%d' - Got '%d'\n", me, i);
}

/* terminate the thread */
pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
int thr_id; /* thread ID for the newly created thread */
pthread_t p_thread; /* thread's structure */
int a = 1; /* thread 1 identifying number */
int b = 2; /* thread 2 identifying number */

signal(mySig, mySigHandle);
/* create a new thread that will execute 'do_loop()' */
thr_id = pthread_create(&p_thread, NULL, do_loop, (void*)&a);
/* run 'do_loop()' in the main thread as well */
do_loop((void*)&b);
return 0;
}

Inside mySigHandle function I want to know which thread has raised the signal(main
thread or created thread)

Last edited by souvik; 08-21-2002 at 06:05 AM.
 
Old 08-21-2002, 05:38 AM   #2
Griffon26
Member
 
Registered: Sep 2001
Location: The Netherlands
Distribution: Gentoo, Debian, Mandrake, LFS
Posts: 182

Rep: Reputation: 30
Re: Signal handling in Multithreaded program

I added code tags for readability.

Quote:
Originally posted by souvik
Code:
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <pthread.h> 

#define mySig 41 

void mySigHandle(int i) 
{ 
    printf("Hi"); 
} 

/* function to be executed by the new thread */ 
void* do_loop(void* data) 
{ 
    int i;                      /* counter, to print numbers */ 
    int j;                      /* counter, for delay        */ 
    int me = *((int*)data);     /* thread identifying number */ 
    kill(getpid(), mySig); 

    for (i=0; i<10; i++) { 
        for (j=0; j<500000; j++) /* delay loop */ 
            ; 
        printf("'%d' - Got '%d'\n", me, i); 
    } 

    /* terminate the thread */ 
    pthread_exit(NULL); 
} 

int main(int argc, char* argv[]) 
{ 
    int        thr_id;         /* thread ID for the newly created thread */ 
    pthread_t  p_thread;       /* thread's structure                     */ 
    int        a         = 1;  /* thread 1 identifying number            */ 
    int        b         = 2;  /* thread 2 identifying number            */ 

    signal(mySig, mySigHandle); 
    /* create a new thread that will execute 'do_loop()' */ 
    thr_id = pthread_create(&p_thread, NULL, do_loop, (void*)&a); 
    /* run 'do_loop()' in the main thread as well */ 
    do_loop((void*)&b); 
    return 0; 
} 

Inside do_loop function I want to know which thread has raised the signal(main
thread or created thread)
I suppose you mean you want to know that in the mySigHandle function.

I'm not an expert on signals, but it's my educated guess that you need to use things like message queues/mailboxes if you want to communicate more information than just the signal itself.
 
Old 08-22-2002, 10:21 AM   #3
no2nt
Member
 
Registered: Aug 2001
Location: South Carolina, USA
Distribution: Redhat 8.0/Custom
Posts: 96

Rep: Reputation: 16
Post Semaphore example

Had some fun with the code you posted. I used semaphores to
lock/unlock a common resource between threads. You may also
want to see pthread_mutex_init(). I have to admit my code does
have some problems (even numbered threads just won't start!).
Hope this helps.

Code:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>

#define mySig 41
#define THREADS 25

struct thread_data
{
    int thread_id;
    int sem_id;
};

int sem_id;
int gloThreadId = 0;

/* 
 * gotta put this in per semctl man page
 */
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun {
  int val;                    /* value for SETVAL */
  struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
  unsigned short int *array;  /* array for GETALL, SETALL */
  struct seminfo *__buf;      /* buffer for IPC_INFO */
};
#endif

void mySigHandle(int i)
{
    printf("Thread %d: Hi\n", gloThreadId);
}

void request_sem(int semid, int i)
{
    struct sembuf sbuf;
    
    sbuf.sem_num= 0;
    sbuf.sem_op = -1;
    sbuf.sem_flg = SEM_UNDO;
    printf("Thread %d requesting lock\n", i);
    semop(semid, &sbuf, 1);
}

void release_sem(int semid, int i)
{
    struct sembuf sbuf;
    
    sbuf.sem_num = 0;
    sbuf.sem_op = 1;
    sbuf.sem_flg = SEM_UNDO;
    printf("Thread %d releasing lock\n", i);
    semop(semid, &sbuf, 1);
}
    
/* function to be executed by the new thread */
void* do_loop(void* data)
{
    int i;                      /* counter, to print numbers */
    int j;                      /* counter, for delay        */
    int me = (*(struct thread_data*)data).thread_id;     /* thread identifying number */
    int semid = (*(struct thread_data*)data).sem_id;	/* semaphore id number */

    printf("Thread %d starting up!\n", me);

    request_sem(semid, me); 
    gloThreadId = me;     
    kill(getpid(), mySig);
    release_sem(semid, me);

    for (i=0; i<10; i++) 
    {
	sleep(1);
        //printf("Thread '%d' = '%d'\n", me, i);
    }

    /* terminate the thread */
    pthread_exit(NULL);
}

struct pthread_stuff
{
    int thread_id;
    pthread_t p_thread;
} pthread_array[50];

int main(int argc, char* argv[])
{
    union semun sun;
    struct thread_data tdata;
    int i;

    /* create a semaphore */
    tdata.sem_id = semget(IPC_PRIVATE, 1, SHM_R | SHM_W);

    if(tdata.sem_id != 1)
    {
	/* set resource to 1 */
	sun.val = 1;
	if( semctl(tdata.sem_id, 0, SETVAL, sun) == -1 )
	{
	    printf("bailing out: semctl() failed [%s]\n", strerror(errno));
	    exit(2);
	}
    }
    else
    {
	printf("bailing out: semget() problems [%s]\n", strerror(errno));
    }
	
    signal(mySig, mySigHandle);

    for( i = 1; i <= THREADS; i++ )
    {
	printf("i = %d\n", i);
	/* fixup tdata for thread 1 */
	tdata.thread_id = i;
	/* create a new thread that will execute 'do_loop()' */
	pthread_array[i].thread_id = pthread_create(&pthread_array[i].p_thread, NULL, do_loop, (void*)&tdata);

	if( pthread_array[i].thread_id != 0 )
	{
	    printf("Thread not created! %d\n", i);
	}
    }

    /* fixup tdata for thread 2; could be done in a for loop for multiple threads*/
    tdata.thread_id = i++;
    /* run 'do_loop()' in the main thread as well */
    do_loop((void*)&tdata);
    
    /* clean up after ourselves */
    semctl(tdata.sem_id, 0, IPC_RMID, 0);
    return 0;
}
 
Old 08-23-2002, 03:28 AM   #4
souvik
LQ Newbie
 
Registered: Apr 2001
Location: Calcutta, India
Posts: 16

Original Poster
Rep: Reputation: 0
A point to note

Thanks for your reply, but that is not the case that I want
In the previous case you are throwing that signal then you can have that luxury to get a lock, change the global variable to the current thread id, throw signal and unlock it, but think about signals thrown by system such as SIGSEGV then how will you get the thread-id inside that signal handler.
 
Old 08-23-2002, 07:28 AM   #5
no2nt
Member
 
Registered: Aug 2001
Location: South Carolina, USA
Distribution: Redhat 8.0/Custom
Posts: 96

Rep: Reputation: 16
Getting on a tangent here:
Would it be practical or possible to extend the functions in signal.h to
accept variable length arguments as a last parameter? I would assume
that this would make the functions backwards compatible with older
programs and would allow you to pass data.

typedef void (*__sighandler_t) (int, ... );
extern int kill( __pid_t __pid, int __sig, ...) __THROW;

I really don't know if this would be legal code.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Threads in signal handling shilpig Programming 3 08-20-2009 03:14 AM
Signal handling......... rajsun Programming 2 06-28-2005 08:10 AM
Signal handling from bash shy Programming 2 11-20-2004 08:41 AM
Signal Handling with LinuxThrreads TedMaul Programming 1 05-01-2004 01:56 PM
Signal handling Mohsen Programming 2 07-30-2003 06:55 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration