Могу ли я отправлять сигналы в разные темы

Скажем, у меня есть поток A, который хочет отправлять сигналы потокам B, C и D. Могу ли я сделать что-то подобное?

SendSignalTo( ThreadB, SIGUSR1 );
SendSignalTo( ThreadC, SIGUSR1 );
SendSignalTo( ThreadD, SIGUSR1 );

С обработчиком сигнала SIGUSR1, определенным по-разному для потоков B, C и D, как показано ниже.

void SIGUSR1_Handler_for_ThreadB(...){...}
void SIGUSR1_Handler_for_ThreadC(...){...}
void SIGUSR1_Handler_for_ThreadD(...){...}

А если нет, то какова альтернатива.

3

Решение

Вы можете отправить сигнал определенной теме, используя pthread_kill(), или, если вы не против того, чтобы быть специфичным для GNU, используйте pthread_sigqueue() (который может указать один int или же void * обработчик может получить доступ через info->si_value).

Для каждого сигнала есть только один обработчик сигнала. Это означает, что определенный сигнал всегда будет вызывать одну и ту же функцию-обработчик, независимо от того, каким потоком он является. Если один поток устанавливает новый обработчик сигнала, обработчик сигнала изменится для всех потоков.

Однако обходной путь тривиален: используйте указатель функции для каждого потока, чтобы определить, какую функцию должен вызывать обработчик сигнала. Просто запомните ограничения обработчика сигналов — вы можете использовать только безопасные функции асинхронного сигнала в обработчике сигнала.

/* Simplify by defining the signal handler function type, assume SA_SIGINFO */
typedef void (*signal_handler_t)(int, siginfo_t *, void *);

/* Per-thread variable pointing to the desired function */
static __thread signal_handler_t  thread_handler = NULL;

/* Process-wide actual signal handler */
static void signal_handler(int signum, siginfo_t *info, void *context)
{
signal_handler_t  func;

func = __sync_fetch_and_or(&thread_handler, (signal_handler_t)0);

if (func)
func(signum, info, context);
}

Атомная нагрузка (__sync_fetch_and_or()) позволяет тривиально изменить обработчик для каждого потока, используя простое атомарное хранилище в любой момент времени, даже не блокируя сигнал. Переключение на функцию new_thread_handler затем

    signal_handler_t  func;

do {
func = thread_handler;
} while (!__sync_bool_compare_and_swap(&thread_handler, func, new_thread_handler));

__sync_fetch_and_or() и функциональный переключатель может быть заменен одним стилем C ++ 11 __atomic_ звоните, но GCC у меня пока не хватает, поэтому я все еще использую старый стиль __sync_ звонки.

POSIX также поддерживает реальное время сигналы, SIGRTMIN+0, SIGRTMIN+1, .., SIGRTMAX, Они имеют дополнительное преимущество, заключающееся в том, что более чем один из них может одновременно находиться на рассмотрении. Они гораздо лучше подходят для такого рода вещей, чем традиционные сигналы.

3

Другие решения

И да и нет.

Новым для меня является функция pthread_kill (), которая позволяет отправлять сигналы потокам в рамках одного и того же процесса.

http://linux.die.net/man/3/pthread_kill

Внимательно прочитайте заметки внизу страницы …

Расположение сигналов распространяется на весь процесс: если установлен обработчик сигнала, обработчик будет вызываться в потоке потока, но если расположение сигнала равно «стоп», «продолжить» или «завершить», это действие повлияет на весь процесс.

Я понимаю, что будет вызван обработчик процесса, и тогда вы сможете предпринять соответствующие действия, зная, что обработчик вызывался только для этого потока, если вы удовлетворяете этим условиям.

4

По вопросам рекламы [email protected]