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

发布于 2024-09-25 07:20:02 字数 574 浏览 3 评论 0原文

我正在编写一个基本的用户级线程库。创建线程的函数原型是 <代码> 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 是怎么做的吗?

I am writing a basic user level thread library. The function prototype for thread creation is

thr_create (start_func_pointer,arg)
{
make_context(context_1,start_func)
}

start_func will be user defined and can change depending on user/program

once after creation of thread, if I start executing it using
swapcontext(context_1,context_2)

the function start_func would start running. Now , if a signal comes in , I need to handle it. Unfortunately, I just have the handle to start_func so I cant really define signal action inside the start_func

is there a way I can add a signal handling structure inside the start_function and point it to my code. something like this


thr_create (start_func_pointer,arg)
{
start_func.add_signal_hanlding_Structure = my_signal_handler();
make_context(context_1,start_func)
}

Does anybody know how posix does it ?

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

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

发布评论

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

评论(1

掀纱窥君容 2024-10-02 07:20:02

如果您正在谈论从正在运行的实际操作系统捕获真实信号,我相信您将必须在应用程序范围内执行此操作,然后将信号向下传递到每个线程(稍后会详细介绍)。问题在于,如果两个(或更多)线程尝试使用使用 SIGALRMalarm ,事情就会变得复杂——当真正的信号发生时,你可以捕获它,但是你将它传递给谁(一个或所有线程?)。

如果您正在讨论使用您的库在程序内的线程之间发送和捕获信号,那么向线程发送信号将导致它被标记为准备运行,即使它之前正在等待其他东西,然后任何信号处理功能将从您的线程恢复代码中调用。如果我记得您之前的问题,您有一个名为 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 (这只是我出于演示目的而编写的信号)。

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

If you are talking about catching real signals from the actual operating system you are running on I believe that you are going to have to do this application wide and then pass the signals on down into each thread (more on this later). The problem with this is that it gets complicated if two (or more) of your threads are trying to use alarm which uses SIGALRM -- when the real signal happens you can catch it, but then who do you deliver it to (one or all of the threads?).

If you are talking about sending and catching signals just among the threads within a program using your library then sending a signal to a thread would cause it to be marked ready to run, even if it were waiting on something else previously, and then any signal handling functionality would be called from your thread resume code. If I remember from your previous questions you had a function called thread_yield which was called to allow the next thread to run. If this is the case then thread_yield needs to check a list of pending signals and preform their actions before returning to where ever thread_yield was called (unless one of the signal handlers involved killing the current thread, in which case you have to do something different).

As far as how to implement registering of signal handlers, in POSIX that is done by system calls made by the main function (either directly or indirectly). So you could have:

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;
}

Now, from another thread you can send this thread a SIGFOO (which is just a signal I made up for demonstration purposes).

Each of your thread control blocks (or whatever you are calling them) will have to have a signal handler table (or list, or something) and a pending signal list or a way to mark the signals as pending. The pending signals will be examined (possibly in some priority based order) and the handler action is done for each pending signal before returning to that threads normal code.

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