使用setjump loopjump在线程中跳转的问题

发布于 2022-09-11 20:43:31 字数 1662 浏览 8 评论 0

使用setjump loopjump在线程中跳转的问题

使用setjump到另一个线程中跳转,跳转成功了,后面的代码不执行了

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include<setjmp.h>
jmp_buf buf;


void *print_a(void *);

void *print_b(void *);

//线程A方法
void *print_a(void *a) {


    for (int i = 0; i < 5; ++i) {
        sleep(1);
        printf("aaaa \n");

        int jmpret = setjmp(buf);
        if (!jmpret) {
            printf("!jmpret  \n");
        } else {
            printf("继续执行线程1\n");
        }

    }
    return NULL;
}

//线程B方法
void *print_b(void *b) {

    for (int i = 0; i < 5; ++i) {
        sleep(1);
        printf("bbbb \n");

        if (i == 3) {
            printf("进入线程2 \n");
            longjmp(buf, 1);
        }
    }
    return NULL;
}

int main() {

    pthread_t t0;
    pthread_t t1;

    //创建线程A
    if (pthread_create(&t0, NULL, print_a, NULL) == -1) {
        printf("fail to create pthread t0 \n");
        exit(1);
    }

    if (pthread_create(&t1, NULL, print_b, NULL) == -1) {
        printf("fail to create pthread t1 \n");
        exit(1);
    }

    //等待线程结束
    void *result;
    if (pthread_join(t0, &result) == -1) {
        printf("fail to recollect t0 \n");
        exit(1);
    } else {
        printf("t0 success \n");
    }

    if (pthread_join(t1, &result) == -1) {
        printf("fail to recollect t1 \n");
        exit(1);
    } else {
        printf("t1 success \n");
    }

    getchar();
    return 0;
}

主线程的getchar也不执行了
这是为何?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌酱 2022-09-18 20:43:31

讲真,我没想到还能这么用....

setjmp/longjmp is implemented by saving the register (including stack and code pointer etc) when first passed, and restoring them jumping.

当线程b通过 longjmp跳到print_a时,它的栈帧和线程a的栈帧所在的内存就是一个地方了 (原来栈的内存没人管)。当线程a退出时,自然要弹出所有栈帧,那么线程b之后对栈访问就是对非法内存的访问了。

就像你把双胞胎中的弟弟的头嫁接到哥哥身上,哥哥变成了连体婴儿,哥哥挂掉之后,弟弟也活不成了,反之也是

说不完的你爱 2022-09-18 20:43:31

longjmp 不能跨线程。

C11 7.13.2.1 / 2:

The longjmp function restores the environment saved by the most recent invocation of
the setjmp macro in the same invocation of the program with the corresponding
jmp_buf argument. If there has been no such invocation, or if the invocation was from
another thread of execution, or if the function containing the invocation of the setjmp
macro has terminated execution in the interim, or if the invocation of the setjmp
macro was within the scope of an identifier with variably modified type and execution has
left that scope in the interim, the behavior is undefined

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文