如何在没有取消点的情况下取消 pthread

How to cancel a pthread without cancellation point

我的应用程序使用第 3 方库 (dcerpc) 作为 rpc 服务器。 假设第 3 方函数位于命名空间 third.

我在线程中调用 third::listen,以侦听传入请求。

"Third" 提供了所有中断此侦听并正确退出线程的机制,但要么它不起作用,要么我没有以正确的方式进行。 我首先尝试使用库工具(演示示例、邮件列表、浏览源代码以了解...)但没有成功。

所以我尝试了另一种方法:暴力杀死监听线程。 但是 third::listen 没有取消点,我猜。

所以这段代码(我用上面的监听函数模拟third::listen):

void* listen(void*)
{
    cout << "listening for calls...." << endl;

    while (true) {}
    printf ("Server stoppped listening\n");
    return 0;
}


int main()
{

    pthread_t thread = 0;

    int res = pthread_create(&thread, 0, listen, 0);
    cout << "pthread_create res: " << res << endl;

    sleep(1);

    bool isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
    cout << "Thread is running: " << isThreadRunning << endl;

    res = pthread_cancel(thread);
    cout << "pthread_cancel res: " << res << endl;

    sleep(1);

    isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
    cout << "Thread is running: " << isThreadRunning << endl;

    res = pthread_join(thread, 0);
    cout << "pthread_join res: " << res << endl;

    return 0;
}

将输出:

pthread_create res: 0
listening for calls....

Thread is running: 1
pthread_cancel res: 0
Thread is running: 1

和pthread_join(thread, 0)块(逻辑因为没有取消点)。

我的问题:如何终止此线程!!

我尝试使用信号,但它停止了我的整个进程,而不仅仅是线程。

我最后的尝试是在专用的 fork 进程中隔离监听,但在我的项目上下文中,fork 真的很痛苦(那是另一回事)。

非常感谢您的帮助。

尼古拉斯

一个线程能否被取消取决于它的取消状态类型。默认状态为 enabled。所以没关系。但是默认类型是deferred。这意味着当您向线程发送取消请求时,它会被推迟,直到它到达取消点。由于您的线程在空循环中没有执行任何操作,因此它根本没有到达取消点。因此,它不会响应 pthread_cancel().

您可以将线程的取消类型设置为 PTHREAD_CANCEL_ASYNCHRONOUS,这通常会使线程退出。致电

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);

循环之前。

或者您可以调用作为取消点的函数之一。例如,在循环内执行 fflush(stdout);

POSIX 列出一些功能作为取消点。有关此类列表,请参阅 cancellation points

根据您提供的有限信息,我无法对不响应退出线程的“第 3 方”库发表任何评论。