【问题标题】:linux shared library to support multi threaded application callbackslinux共享库支持多线程应用回调
【发布时间】:2015-06-25 08:34:25
【问题描述】:

我需要创建一个共享库来公开一组 API,这些 API 将被多个进程使用,这些进程可能有多个线程从其中调用 API。

这个共享库又使用另一个我需要注册回调的第 3 方共享库。第 3 方库从不同的线程调用注册的回调。

我想知道如何在调用我的库中定义的 API 时阻止线程,并在我从 3rd 方库获得回调时释放它。此锁定不应阻止其他线程调用相同的 API...!

我正在使用 pthread 库来创建我的库。

伪代码:

我的图书馆:

int lib_init()
{
    register_callback(callback);
}

int lib_deinit()
{
    unregister_callback();
}

int callback(void *)
{
    <unblock the functions>
}

int function1(int, int)
{
    perform_action();
    <should block till I get a callback from 3rd party library>
}

int function2(char, char)
{
    perform_action();
    <should block till I get a callback from 3rd party library>
}

第三方库:

int register_callback(callback)
{
    ....
    launch_thread();
    ....
}

int unregister_callback()
{
    ....
    terminate_thread();
    ....
}

int perform_action()
{
    /* queue action */
}

void* thread(void*arg)
{
    /* perform the action & invoke callback */
    invoke_callback();
}

应用:

main()
{
    init_lib();
    ....
    create_new_thread();
    ....
    function1(10, 20);
    ....
    function2('c', 'd');
}

another_thread()
{
    function2('a', 'b');
    ....
}

我无法解决的确切问题是我需要设置什么(如何)锁定机制来阻止对我的库中定义的函数的调用并等待来自 3rd 方库的回调,前提是我的库应该被使用在多进程和多线程环境中。

【问题讨论】:

    标签: c++ linux multithreading pthreads shared-libraries


    【解决方案1】:

    使用普通的 pthreads 接口,您可以使用条件变量:

    int lib_init()
    {
        pthread_cond_init(&cond, NULL);
        pthread_mutex_init(&mutex, NULL);
        register_callback(callback);
    }
    
    int lib_deinit()
    {
        unregister_callback();
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    }
    
    int callback(void *p)
    {
        pthread_mutex_lock(&mutex);
        result[??] = p;
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);
    }
    
    int function1(int, int)
    {
        result[??] = NULL;
        perform_action();
    
        pthread_mutex_lock(&mutex);
        while (result[??] == NULL)
            pthread_cond_wait(&cond, &mutex);
        pthread_mutex_unlock(&mutex);
    }
    
    int function2(char, char)
    {
        result[??] = NULL;
        perform_action();
    
    
        pthread_mutex_lock(&mutex);
        while (result[??] == NULL)
            pthread_cond_wait(&cond, &mutex);
        pthread_mutex_unlock(&mutex);
    }
    

    pthread_cond_wait() 在等待时解锁互斥锁。

    result[??] 是您必须想出的某些方法的替代,以将特定的回调调用链接到与之相关的特定 function1()function2() 调用.

    【讨论】:

    • 感谢@caf,我可以使用您提供的示例代码开始我的实现...!
    【解决方案2】:

    如果你会使用C++11,你可能对std::condition_variable & 朋友感兴趣。您应该在您的函数 API 中创建一个条件变量,将其传递给您的回调,将您的回调注册到第 3 方库,并让您的 API 函数等待它。然后,您可以在回调结束时取消阻止它。

    伪代码:

    void your_API_f()
    {
        define std::condition_variable;
        pack it with your callback parameters
        register the callback to 3rd party lib
        invoke 3rd party func
        wait on your condition variable
    }
    
    void your_callback(Parameters* p)
    {
        do whatever...
        notify p->your_cond_variable you have finished
    }
    

    【讨论】:

      【解决方案3】:

      就可用性和标准而言,您的最佳选择可能是使用 Boost:

      Boost.threads 用于多线程,Boost::interprocess 用于进程间通信;看看IPC synchronization mechanisms

      对于多线程应用程序,具有某种消息队列(上面链接的底部)以线程安全的方式从任何线程获取消息是非常典型的,而无限循环中的另一个线程从中获取消息队列。这些消息通常包括一些命令、一些有效负载和一个指向执行线程应该将其结果放在哪里的指针。这也可能是另一个 boost::interprocess 通信结构。

      【讨论】:

      • 由于需要在其中部署库的环境(平台),我无法使用 Boost。我只能使用 pthread 库,我需要编写支持库要求所需的所有内容......!
      • 感谢 Boost 许可证,您可以简单地在应用程序中包含所有需要的 boost 头文件和源文件。这和自己写是一样的。 Boost 也非常便携。
      猜你喜欢
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多