linux共享库支持多线程应用程序回调

时间:2015-06-25 08:34:25

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

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

这个共享库依次使用另一个我需要注册回调的第三方共享库。第三方库从另一个线程调用已注册的回调。

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

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

Psudo代码:

我的图书馆:

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');
    ....
}

我无法解决的确切问题是我需要采用什么(如何)锁定机制来阻止对我的库中定义的函数的调用?等待第三方图书馆的回调,前提是我的图书馆将用于多进程和图书馆。多线程环境。

3 个答案:

答案 0 :(得分:1)

如果你可以使用C ++ 11,你可能会对std::condition_variable&amp;朋友。您应该在函数API中创建一个条件变量,将其传递给您的回调,将您的回调注册到第三方库,并让您的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
}

答案 1 :(得分: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()与之相关的电话。

答案 2 :(得分:-1)

通过可用性和标准的最佳选择可能是使用Boost:

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

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