LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Threads in signal handling (https://www.linuxquestions.org/questions/programming-9/threads-in-signal-handling-205700/)

shilpig 07-16-2004 01:17 AM

Threads in signal handling
 
Pls help me in the program attached.
I am not able to figure out why with thread, signal handler doesnot return.

Hoping to get the solution.

My Program:
#include<unistd.h>
#include<signal.h>
#include<time.h>
#include<stdio.h>

#define OUR_CLOCK CLOCK_REALTIME
// General Hash Defines
#define FALSE 0
#define TRUE 1

int c;
struct itimerspec i;
struct timespec resolution;
struct sigaction sa;
sigset_t allsigs;
struct sigevent timer_event;
timer_t mytimer;
pthread_t th;


void timer_intr(int sig, siginfo_t *extra, void *cruft)
{
int noverflow;
printf("in timer_intr\n");
if(noverflow = timer_getoverrun(*(timer_t *) extra->si_value.sival_ptr))
{
printf("timer has overflowed -- error !\n");
}
return;

}

void th_proc( )
{
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_SIGINFO; //real-time signal
sa.sa_sigaction=timer_intr; //pointer to action

if(sigaction(SIGRTMIN, &sa, NULL) < 0)
{
perror("sigaction error \n");
exit(1);
}

//
// first determine whether the desired clock exists
//

if (clock_getres(OUR_CLOCK, &resolution) < 0)
{
perror("clock_getres error\n");
exit(1);
}

printf("clock resolution %d sec %d nsec \n", resolution.tv_sec, resolution.tv_nsec);

//
// create a timer based upon the CLOCK_REALTIME clock
//

i.it_interval.tv_sec = 1;//0;

// set resolution to one-tenth of the maximum allowed

i.it_interval.tv_nsec = resolution.tv_nsec*10;
i.it_value = i.it_interval;

//
// this describes the asynchronous notification to be posted
// upon this timer's expiration:
//
// - use signals
// - send SIGRTMIN
// - send extra data consisting of a pointer back to the timer ID
// cannot pass the timer ID itself because we haven't created it
// yet.
//

timer_event.sigev_notify = SIGEV_SIGNAL;
timer_event.sigev_signo = SIGRTMIN;
timer_event.sigev_value.sival_ptr = (void *)&mytimer;

if (timer_create(OUR_CLOCK, &timer_event, &mytimer) < 0)
{
perror("timer create error\n");
exit(1);
}

// relative timer, go off at the end of the interval

if(timer_settime(mytimer, 0 , &i, NULL) < 0)
{
perror("settimer\n");
exit(3);
}

printf("timer_settime\n");

sigemptyset(&allsigs);
while(1)
{
printf("before\n");
sigsuspend(&allsigs);
printf("after\n");
}
exit(4);
}


static int launchThread()
{
int iRet = 0;
int iResult = TRUE;

iRet = pthread_create( &th, NULL, (void *)(&th_proc), // thread Proc
NULL);
if ( iRet != 0 )
{
printf("Failed to create thread : Err %d.\n", iRet);
iResult = FALSE;
}

return iResult;
}


int main()
{

// Signal Handler doesnot return to the calling i.e "after" is not printed. WHY?
if( launchThread() == FALSE)
{
printf("Failed to launch thread.\n");
return 1;
}

// If I call thread_proc (dont create thread) and comment launchThread, I get the correct output
//th_proc();

printf(" in main\n");

while(1)
{
sleep(100);
}
}



My Makefile:
all:
cc -g -pthread -lrt -o try4.o try4.c
clean:
rm -f try4.o

The_Nerd 07-16-2004 12:39 PM

printf doesn't automatically print to the console. Printf buffers its output, and when the buffer is full, or a certain amount of time has elapsed then it outputs its buffer to the screen. Use fprintf(stderr, "Mystring %d", i); instead.

Oh, and you do know that when you call an exit(0); it will exit your program, not the thread. (Someone correct me if I am wrong about this, but I REALLY don't think I am). Use return instead.

Hope that helps.

infamous41md 07-16-2004 01:10 PM

u need to post that code inside of CODE TAGS please.

naveenisback 08-20-2009 03:14 AM

put the code in code tag
 
Code:

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

#define OUR_CLOCK CLOCK_REALTIME
// General Hash Defines
#define FALSE 0
#define TRUE 1

int c;
struct itimerspec i;
struct timespec resolution;
struct sigaction sa;
sigset_t allsigs;
struct sigevent timer_event;
timer_t mytimer;
pthread_t th;


void timer_intr(int sig, siginfo_t *extra, void *cruft)
{
int noverflow;
printf("in timer_intr\n");
if(noverflow = timer_getoverrun(*(timer_t *) extra->si_value.sival_ptr))
{
printf("timer has overflowed -- error !\n");
}
return;

}

void th_proc( )
{
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_SIGINFO; //real-time signal
sa.sa_sigaction=timer_intr; //pointer to action

if(sigaction(SIGRTMIN, &sa, NULL) < 0)
{
perror("sigaction error \n");
exit(1);
}

//
// first determine whether the desired clock exists
//

if (clock_getres(OUR_CLOCK, &resolution) < 0)
{
perror("clock_getres error\n");
exit(1);
}

printf("clock resolution %d sec %d nsec \n", resolution.tv_sec, resolution.tv_nsec);

//
// create a timer based upon the CLOCK_REALTIME clock
//

i.it_interval.tv_sec = 1;//0;

// set resolution to one-tenth of the maximum allowed

i.it_interval.tv_nsec = resolution.tv_nsec*10;
i.it_value = i.it_interval;

//
// this describes the asynchronous notification to be posted
// upon this timer's expiration:
//
// - use signals
// - send SIGRTMIN
// - send extra data consisting of a pointer back to the timer ID
// cannot pass the timer ID itself because we haven't created it
// yet.
//

timer_event.sigev_notify = SIGEV_SIGNAL;
timer_event.sigev_signo = SIGRTMIN;
timer_event.sigev_value.sival_ptr = (void *)&mytimer;

if (timer_create(OUR_CLOCK, &timer_event, &mytimer) < 0)
{
perror("timer create error\n");
exit(1);
}

// relative timer, go off at the end of the interval

if(timer_settime(mytimer, 0 , &i, NULL) < 0)
{
perror("settimer\n");
exit(3);
}

printf("timer_settime\n");

sigemptyset(&allsigs);
while(1)
{
printf("before\n");
sigsuspend(&allsigs);
printf("after\n");
}
exit(4);
}


static int launchThread()
{
int iRet = 0;
int iResult = TRUE;

iRet = pthread_create( &th, NULL, (void *)(&th_proc), // thread Proc
NULL);
if ( iRet != 0 )
{
printf("Failed to create thread : Err %d.\n", iRet);
iResult = FALSE;
}

return iResult;
}


int main()
{

// Signal Handler doesnot return to the calling i.e "after" is not printed. WHY?
if( launchThread() == FALSE)
{
printf("Failed to launch thread.\n");
return 1;
}

// If I call thread_proc (dont create thread) and comment launchThread, I get the correct output
//th_proc();

printf(" in main\n");

while(1)
{
sleep(100);
}
}



All times are GMT -5. The time now is 11:08 PM.