簡體   English   中英

setjmp 和 longjmp 在兩個函數之間切換的問題

[英]problem with setjmp and longjmp to switch between 2 functions

我正在嘗試實現一個在函數 fun() 和 main() 之間連續切換的代碼,它們除了無限地在屏幕上打印之外什么都不做。 我試圖通過 setjmp 和 longjmp 切換,並在 C 中使用 SIGALRM 信號。但是當我運行它時,它只工作一次,然后不切換。

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

jmp_buf b1, b2;
int cur = 0;

void handlesig(int sig) {
    if(!cur) {
        cur = 1;
        setjmp(b2);
        longjmp(b1, 1);
    }
    else {
        cur = 0;
        setjmp(b1);
        longjmp(b2, 1);
    }
}

void fun() {    
    while(1) {
        printf("I am in function fun()\n");
        for(int x = 0; x < 100000000; x++);
    }
}

int main() {    
    signal(SIGALRM, handlesig);
    ualarm(900000, 900000);                     //send SIGALRM after each 900000 microseconds
    if(!setjmp(b1))
        fun();                                  //will be run when setjmp returns 0
    while(1) {                      
        printf("I am in function main()\n");    //will be run when setjmp returns 1
        for(int x = 0; x < 100000000; x++);
    }
    return 0;
}

我不明白這段代碼有什么問題。

您的程序具有未定義的行為,因為一旦調用longjmp (在下一行),信號處理程序中在b1b2上調用setjmp的塊的生命周期就會結束。 下次您調用longjmp試圖返回不再有效的jmp_buf ,行為未定義,這表現為狀態完全損壞。

您可以編寫一個 hack來解決這個問題,方法是使用sigaltstackSA_ONSTACK標志讓信號處理程序具有多個堆棧,這樣即使jmp_buf正式無效,它實際上也不會被破壞。 但這不是一個有效的程序,只是一個碰巧在某些系統(不是全部)上實際運行的程序。 最終,沒有(有效/可靠的)方法可以使用setjmplongjmp來完成您的要求; 上下文切換需要比它們提供的更嚴格的原語。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM