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