Operating System - HP-UX
1753779 Members
7566 Online
108799 Solutions
New Discussion юеВ

Trouble with timer and sleep

 
SOLVED
Go to solution
wanyingjie
New Member

Trouble with timer and sleep

Hello, I am trying to used timer to control my business jump out when timeout,as i list below. It can't work when my_business contain sleep. I know it is a bad idea to mixed use sleep and alarm,can anyone suggest some other api to finish it.

Appreciate your assistance,thank you!!






#include

#include

#include


void sighandle(int);


static sigjmp_buf s_env;

void my_business()
{
/* call the real service function */
for(int i = 0; i < 2147483647;i ++){
rc = rc + i;
//sleep(1);
}
}

sigjmp_buf *_px_get_jmpbuf(void)
{
return &s_env;
}

int main() {
// Get system call result to determine successful or failed

int res = 0;
int rc = 0;

// Register printMsg to SIGALRM
struct itimerval tick;

struct sigaction action, oldaction;;


action.sa_flags = 0;
action.sa_handler = sighandle;

sigfillset(&action.sa_mask);
sigaction(SIGALRM, &action, &oldaction);

//sigaction(SIGINT, &action, &oldaction);

// Initialize struct

memset(&tick, 0, sizeof(tick));

// Timeout to run function first time

tick.it_value.tv_sec = 5; // sec

tick.it_value.tv_usec = 0; // micro sec.

// Interval time to run function

tick.it_interval.tv_sec = 1;

tick.it_interval.tv_usec = 0;

// Set timer, ITIMER_REAL : real-time to decrease timer,

//send SIGALRM when timeout

res = setitimer(ITIMER_REAL, &tick, NULL);

if (res) {

printf("Set timer failed!!\n");

}


// Always sleep to catch SIGALRM signal
if(sigsetjmp(s_env, 1) == 0)
{
my_business();

printf("business end ");
}
else
{
printf("business interupt");
}



return 0;
}

void sighandle(int sig) {

if (sig != SIGALRM){
printf("Receive SIG = %d\n",sig);
return;
}

printf("Receive SIG\n");
siglongjmp(*_px_get_jmpbuf(), 1);
}





12 REPLIES 12
Dennis Handly
Acclaimed Contributor

Re: Trouble with timer and sleep

nanosleep(2) works fine. It also says:
The use of the nanosleep() function has no effect on the action or blockage of any signal.
wanyingjie
New Member

Re: Trouble with timer and sleep

Thank you for your answer,but we can't limit user not to use sleep in my_business.Do you have some advice about timer.
Dennis Handly
Acclaimed Contributor

Re: Trouble with timer and sleep

>we can't limit user not to use sleep in my_business

I tried doing this but it didn't work:
int ret = sleep(1);
if (ret != 0) {
printf("Assume SIGALRM on sleep\n");
siglongjmp(*_px_get_jmpbuf(), 1);
wanyingjie
New Member

Re: Trouble with timer and sleep

I modified my_business,result is sleep interrupted!The program exited and not printf business interupt.But if I remove line 11,result is business interrupt!


1-void my_business()
2-{
3- int ret = 0;
4- int rc;
5-
6- /* call the real service function */
7- for(int i = 0; i < 2147483647;i ++){
8- rc = rc + i;
9- ret = sleep(2);
10- if(ret != 0){
11- printf("sleep interrupted!\n");
12- siglongjmp(*_px_get_jmpbuf(), 1);
13- }
14- }
15-}
Dennis Handly
Acclaimed Contributor

Re: Trouble with timer and sleep

>The program exited and not printf business interrupt

I get both.
You may want to add this after the printf:
fflush(stdout);
wanyingjie
New Member

Re: Trouble with timer and sleep

We can't prevent user do anything in business,so do you have advices about timer which will not be effected by sleep.
Laurent Menase
Honored Contributor

Re: Trouble with timer and sleep

poll(0,0,1000);; --> sleep 1sec
tv.tv_sec=1;
tv.tv_usec=0;
select(0,0,0,0,&tv);
---> those 2 don't any sideffect over sigalarm.

else you should probably
alarm(0); just before printf end of business
or a longjump


Dennis Handly
Acclaimed Contributor

Re: Trouble with timer and sleep

>do you have advice about timer which will not be effected by sleep?

Well, sleep seems to block SIGALRM. I don't know about VTALRM? Or more importantly how to enable it.

You could just fool the user by creating your own version of sleep that calls nanosleep.
Laurent Menase
Honored Contributor
Solution

Re: Trouble with timer and sleep

SIGVALARM is used for virtual time timer
If you want to use an other signal
you can use a coprocess for instance


if (!fork())
{
sleep(timeout);
kill(SIGUSR1,getppid());
exit(0);
}
.....



or use timer_create().
- man 2 timers-