printf() 如何作为安全取消点工作?这取决于什么?

问题描述 投票:0回答:1

我有一个小程序,应该创建一个线程并取消它。

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void *thread_function(void *arg)
{
    while(1)
    {
        printf("hello \n"); 
        //sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t thread;

    if(pthread_create(&thread, NULL, thread_function, NULL) != 0)
    {
        perror("Failed to create a thread");
        return -1;
    }

    printf("After sleep in main thread\n");
    if (pthread_cancel(thread) != 0) {
        perror("Failed to cancel thread");
        return EXIT_FAILURE;
    }


    pthread_join(thread, NULL);
    printf("Thread is cancelled\n");
}

如果我在线程函数中使用 sleep(),创建的线程几乎会立即被取消,但如果我使用 printf(),则需要一些时间才能取消它。在 man pthreads 中,我读到 sleep() 是一个安全取消点,而 printf() 可能是一个安全取消点。

它是如何运作的?我的意思是程序在什么时间段内工作 printf() 变成取消点并且我的线程被取消?

而且,如果我使用 time 命令运行程序(也在线程函数中使用 printf()),它可以显示程序运行了 2 秒,但实际上它运行的时间更长。为什么?

PS:抱歉犯了错误,英语不是我的母语。

c pthreads
1个回答
0
投票

如果我在线程函数中使用 sleep(),创建的线程几乎会立即被取消,但如果我使用 printf(),则需要一些时间才能取消它。在 man pthreads 中,我读到 sleep() 是一个安全取消点,而 printf() 可能是一个安全取消点。

也许这是一个语言问题,但“安全”并不是一个合适的描述。 我认为你想要表达的是 POSIX requires

sleep()
是一个取消点,而它仅仅 allows
printf()
是一个取消点。 当然,这意味着它也允许
printf()
not 成为一。

它是如何运作的?我的意思是程序在什么时间段内工作 printf() 变成取消点并且我的线程被取消?

函数不会“变成”取消点。 它要么是一个,要么不是,具体取决于您的系统。

如果某个函数是取消点,并且在取消类型为“deferred”的线程中调用该函数,且该线程有待处理的取消请求,则该线程在调用时会被取消。

POSIX 不要求尝试加入线程在目标线程取消后的任何特定时间内完成,也不要求从取消到加入的时间与不同取消点的使用保持一致,也不要求与其他任何东西保持一致,真的。

但是,我推测您可能会误解您的观察结果,特别是考虑到:

如果我使用 time 命令运行程序(也在线程函数中使用 printf()),它可以显示程序运行了 2 秒,但实际上它运行的时间更长。

您正在紧密循环中运行

printf()
,这将产生大量输出,并且输出到终端的速度可能会非常慢。 对于您的
printf()
来说,线程取消本身可能会发生得很快,但输出的生成时间会更长。 您应该相信
time
对流程时间的测量。

© www.soinside.com 2019 - 2024. All rights reserved.