将信号处理程序添加到C中用于线程库的函数

时间:2010-09-27 21:42:51

标签: c function-pointers signals

我正在编写一个基本的用户级线程库。线程创建的函数原型是 thr_create (start_func_pointer,arg) { make_context(context_1,start_func) }

start_func将由用户定义,可根据用户/程序进行更改

创建线程后,如果我开始执行它 swapcontext(context_1,context_2)

函数start_func将开始运行。现在,如果有信号进来,我需要处理它。不幸的是,我只有start_func的句柄所以我无法在start_func中真正定义信号动作

有没有办法在start_function中添加信号处理结构并将其指向我的代码。像这样的东西

thr_create (start_func_pointer,arg) { start_func.add_signal_hanlding_Structure = my_signal_handler(); make_context(context_1,start_func) } 有人知道posix是怎么做到的吗?

1 个答案:

答案 0 :(得分:1)

如果您正在谈论从正在运行的实际操作系统中捕获实际信号,我相信您将不得不在此应用程序范围内执行此操作,然后将信号传递到每个线程中(稍后将详细介绍)。这个问题是如果你的两个(或多个)线程试图使用alarm使用SIGALRM它会变得复杂 - 当真正的信号发生时你可以捕获它,但是那么谁做你把它交给(一个或所有线程?)。

如果您正在谈论使用您的库在程序中的线程之间发送和捕获信号,那么向线程发送信号将导致它被标记为准备运行,即使它正在等待之前的其他内容,并且然后将从您的线程恢复代码中调用任何信号处理功能。如果我从你之前的问题中记得你有一个名为thread_yield的函数,它被调用以允许下一个线程运行。如果是这种情况,则thread_yield需要检查待处理信号列表并在返回调用thread_yield之前执行其操作(除非其中一个信号处理程序涉及查杀当前线程,其中你不得不做一些不同的事情。)

至于如何实现信号处理程序的注册,在POSIX中由主函数(直接或间接)进行的系统调用完成。所以你可以:

static int foo_flag = 0;

static void foo_handle(int sig) {
     foo_flag = 1;
}

int start_func(void * arg) {
    thread_sig_register(SIGFOO, foo_handle);

    thread_pause();
    // this is a function that you could write that would cause the current thread
    // to mark itself as not ready to run and then call thread_yield, so that
    // thread_pause() will return only after something else (a signal) causes the
    // thread to become ready to run again.


    if (foo_flag) {
        printf("I got SIGFOO\n");
    } else {
        printf("I don't know what woke me up\n");
    }
    return 0;
}

现在,从另一个线程你可以发送一个SIGFOO(这只是我为演示目的而制作的信号)。

每个线程控制块(或任何你调用它们)都必须有一个信号处理程序表(或列表或其他东西)和一个挂起信号列表或一种将信号标记为挂起的方法。将检查待处理的信号(可能以某种基于优先级的顺序),并且在返回到该线程正常代码之前,对每个待处理信号执行处理程序操作。