Потоки APR и обработка сигналов

В настоящее время я пытаюсь реализовать потоки, используя Apache Portable Runtime. Все работает отлично, за исключением того, что я не совсем уверен, что делаю это так, как задумано, из-за отсутствия документации или примеров.

Мне нужны два потока и обработка сигналов, чтобы поймать CTRL-C на консоли, чтобы очистить мой сервер и, возможно, потоки. Это мой текущий подход:

// Define APR thread pool
apr_pool_t *pool;

// Define server
MyServer *server;

// Define threads
apr_thread_t *a_thread, *b_thread;
apr_status_t status;

static void * APR_THREAD_FUNC func_a(apr_thread_t * thread,
void *data) {
// do func_a stuff here
}

static void * APR_THREAD_FUNC func_b(apr_thread_t * thread,
void *data) {
// do func_b stuff here
}

// Cleanup before exit
void cleanup(int s) {
printf("Caught signal %d\n", s);

// Destroy thread pool
apr_pool_destroy(pool);

//apr_thread_exit(a_thread, APR_SUCCESS);
//apr_thread_exit(b_thread, APR_SUCCESS);

//apr_terminate();

// Stop server and cleanup
server->stopServer();
delete server;

exit(EXIT_SUCCESS);
}

int main(void) {
// Signal handling
signal(SIGINT, cleanup);

// Create server
server = MyServerFactory::getServerImpl();

bool success = server->startServer();

// Initialize APR
if (apr_initialize() != APR_SUCCESS) {
printf("Could not initialize\n");
return EXIT_FAILURE;
}

// Create thread pool
if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
printf("Could not allocate pool\n");
return EXIT_FAILURE;
}

// Create a_thread thread
if (apr_thread_create(&a_thread, NULL, func_a, NULL,
pool) != APR_SUCCESS) {
printf("Could not create a_thread\n");
return EXIT_FAILURE;
}

//Create b_thread thread
if (apr_thread_create(&b_thread, NULL, func_b, NULL,
pool) != APR_SUCCESS) {
printf("Could not create b_thread\n");
return EXIT_FAILURE;
}

// Join APR threads
apr_thread_join(&status, a_thread);
apr_thread_join(&status, b_thread);

return EXIT_SUCCESS;
}

Это работает более или менее, как ожидалось. Единственное, в чем я не уверен, так это в том, что очистка работает нормально.

  1. Кажется, что функция очистки вызывается более одного раза (строка «Пойманный сигнал ..» появляется более одного раза на терминале). Есть ли способ предотвратить это? Это проблематично?

  2. Я нашел более одного примера очистки потоков APR после использования. Достаточно ли моего пути или мне нужно кое-что прокомментировать? Или я совершенно не прав?

3

Решение

Очистка потока APR подробно описана в раздел резьбы из APR Tutorial. По порядку шаги очистки выглядят так:

  1. Вызов apr_thread_exit() в самой теме. В то время как потоки Unix завершаются автоматически, потоки Windows — нет. Вызовите эту функцию для переносимости (и для возврата статуса, если необходимо).
  2. Вызов apr_thread_join() в главном потоке ждать завершения всех потоков.
  3. Вызов apr_pool_destroy() освободить основной пул памяти. (Дочерние пулы памяти освобождаются с помощью apr_thread_exit().)
  4. Вызов apr_terminate() освободить другие ресурсы (сокеты и т. д.). Обратите внимание, что просто звонить exit() в другой теме без этих последних шагов может вызвать сбои.

У них также есть краткая программа-пример это демонстрирует некоторые из этих вещей.

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

0

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

Других решений пока нет …