简体   繁体   English

APR线程和信号处理

[英]APR threads and signal handling

I am currently trying to implement threads using the Apache Portable Runtime. 我目前正在尝试使用Apache Portable Runtime实现线程。 Everything works fine, except I am not really sure if I am doing it the way it's intended to do due to lack of documentation or examples. 一切正常,除非我不确定我是否按照预期的方式进行操作,因为缺少文档或示例。

I need two threads and signal handling to catch a CTRL-C on the console to cleanup my server and possibly the threads. 我需要两个线程和信号处理来捕获控制台上的CTRL-C来清理我的服务器和可能的线程。 This is my current approach: 这是我目前的做法:

// 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;
}

This works more or less as expected. 这或多或少按预期工作。 The only thing I am not really sure about is if the cleanup works fine. 我唯一不确定的是清理是否正常。

  1. The cleanup-function seems to be called more then one time (String "Caught signal.." appears more than one time on terminal). 清理功能似乎被多次调用(字符串“Caught signal ..”在终端上出现多次)。 Is there a way to prevent this? 有办法防止这种情况吗? Is this problematic? 这有问题吗?

  2. I found more than one example for cleaning up APR threads after usage. 我发现在使用后清理APR线程的例子不止一个。 Is my way sufficient or do I need some of the commented stuff? 我的方式是否足够,还是需要一些注释的东西? Or am I completely wrong? 还是我完全错了?

APR thread cleanup is explained in decent detail in the threading section of the APR Tutorial . APR教程线程部分中详细解释了APR线程清理。 In order, the cleanup steps look like this: 按顺序,清理步骤如下所示:

  1. Call apr_thread_exit() in the thread itself . 在线程本身中调用apr_thread_exit() While Unix threads terminate automatically, Windows threads do not. 虽然Unix线程自动终止,但Windows线程却没有。 Call this function for portability (and to a return a status, if necessary). 调用此函数以实现可移植性(如果需要,还可以返回状态)。
  2. Call apr_thread_join() in the main thread to wait for the termination of all threads. 在主线程中调用apr_thread_join()以等待所有线程的终止。
  3. Call apr_pool_destroy() to free the main memory pool. 调用apr_pool_destroy()以释放主内存池。 (Child memory pools are freed with apr_thread_exit() .) (使用apr_thread_exit()释放子内存池。)
  4. Call apr_terminate() to release other resources (sockets, etc.). 调用apr_terminate()以释放其他资源(套接字等)。 Note that simply calling exit() in another thread without these final steps can cause crashes . 请注意,在没有这些最终步骤的情况下简单地在另一个线程中调用exit() 会导致崩溃

They also have a brief sample program that demonstrates some of this stuff. 他们还有一个简短的示例程序 ,演示了一些这样的东西。

As for why your signal handler is firing twice, I don't think that has to do with APR. 至于你的信号处理程序发射两次的原因,我不认为这与APR有关。 SIGINT is sent to parent and child processes, so I suspect MyServer is forking a new process and both are invoking the handler. SIGINT被发送到父进程和子进程,所以我怀疑MyServer正在分支一个新进程并且都在调用处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM