APR线程和信号处理



我目前正在尝试使用Apache可移植运行时实现线程。一切都很好,除了我不确定我是否按照它的意图做,因为缺乏文档或示例。

我需要两个线程和信号处理来捕获控制台上的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 %dn", 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 initializen");
    return EXIT_FAILURE;
}
// Create thread pool
if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
    printf("Could not allocate pooln");
    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_threadn");
    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_threadn");
    return EXIT_FAILURE;
}
    // Join APR threads
    apr_thread_join(&status, a_thread);
    apr_thread_join(&status, b_thread);
    return EXIT_SUCCESS;
}

这或多或少符合预期。我唯一不确定的是清理工作是否正常。

  1. 清理函数似乎被调用了不止一次(字符串"Caught signal.."在终端上出现了不止一次)。有办法防止这种情况发生吗?这有问题吗?

  2. 我发现在使用后清理APR线程的示例不止一个。我的方式足够了吗,还是我需要一些评论的东西?还是我完全错了?

APR线程清理在APR教程的线程部分有相当详细的解释。清理步骤如下:

  1. 在线程本身中调用apr_thread_exit() 。Unix线程会自动终止,而Windows线程不会。调用这个函数是为了可移植性(如果有必要,还可以返回一个状态)。
  2. 在主线程中调用apr_thread_join(),等待所有线程结束。
  3. 呼叫apr_pool_destroy()释放主内存池。(子内存池使用apr_thread_exit()释放)
  4. 调用apr_terminate()释放其他资源(socket等)。请注意,在没有这些最后步骤的情况下,在另一个线程中简单地调用exit()可能会导致崩溃。

他们也有一个简短的示例程序来演示这些东西。

至于为什么你的信号处理程序触发两次,我不认为这与apr有关。SIGINT被发送到父进程和子进程,所以我怀疑MyServer正在分叉一个新进程,两者都在调用处理程序。

相关内容

  • 没有找到相关文章

最新更新