Добавление обработчика сигнала к функции в C для библиотеки потоков - PullRequest
1 голос
/ 28 сентября 2010

Я пишу базовую библиотеку потоков пользовательского уровня.Прототип функции для создания потока: 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 Ответ

1 голос
/ 28 сентября 2010

Если вы говорите о перехвате реальных сигналов от реальной операционной системы, на которой вы работаете, я считаю, что вам придется широко использовать это приложение, а затем передавать сигналы вниз в каждый поток (подробнее об этом позже).Проблема в том, что это усложняется, если два (или более) ваших потоков пытаются использовать 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 (это просто сигнал, который я придумал для демонстрационных целей).

Каждый ваш потокблоки управления (или как вы их называете) должны иметь таблицу обработчиков сигналов (или список, или что-то в этом роде) и список ожидающих сигналов или способ пометить сигналы как ожидающие.Ожидающие сигналы будут проверены (возможно, в некотором порядке приоритетов), и действие обработчика будет выполнено для каждого ожидающего сигнала перед возвратом к нормальному коду этих потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...