在保存状态后,我们试图在 C 程序中的多个函数之间切换setjmp
,longjmp
但是对于一个函数,我们能够保存上下文而不是其他两个函数。可能的解决方案是什么。如果需要在代码中进行必要的更改,请提出建议。在o/p
的状态下fun1()
成功保存env1
,我们可以恢复它,但如果fun2()
和fun3()
状态没有保存在env2
, 中env3
。
样品 o/p:
i=0,j=999
i=1,j=998
i=2,j=997
i=3,j=996
ch=a
ch=b
ch=c
ch=d
a=0
a=-1
a=-2
a=-3
i=4,j=995/*The previous value of i is preserved*/
i=5,j=996
i=6,j=994
i=7,j=993
ch=<garbagevalue> /*The previous value of ch is lost*/
ch=<garbagevalue>
ch=<garbagevalue>
ch=<garbagevalue>
a=<garbagevalue> /*The previous value of ch is lost*/
a=<garbagevalue>
a=<garbagevalue>
a=<garbagevalue>
i=8,j=992
and so on..
代码如下:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include<setjmp.h>
#define INTERVAL 5000
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
jmp_buf env1,env2,env3;
int count=0;
void timer_handler (int signum)
{
if(count==0){
count++;
fun1();
}
if(count==1){
count++;
fun2();
}
if(count==2){
count++;
fun3();
}
L1:
if(count==3){
count++;
siglongjmp(env1,7);
}
if(count==4){
count++;
siglongjmp(env2,7);
}
if(count==5){
count++;
siglongjmp(env3,7);
}
count=3;
goto L1;
}
void fun1()
{
struct sigaction sa;
int i=0,j=999;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_flags=SA_NODEFER;
sa.sa_handler = &timer_handler;
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1) {
while(sigsetjmp(env1,3)==0){
sleep(1);
printf("i=%d,j=%d\n",i,j);
i++;
j--;
}
}
}
void fun2()
{
struct sigaction sa;
char ch='a';
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1) {
while(sigsetjmp(env2,2)==0) {
sleep(1);
printf("ch=%c\n",ch);
if(ch=='z')
ch='a';
ch++;
}
}
}
void fun3()
{
struct sigaction sa;
int a=0;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1){
while(sigsetjmp(env3,1)==0){
sleep(1);
printf("a=%d\n",a);
a--;
}
}
}
int main ()
{
timer_handler(1);
return 0;
}