pthread_cancel和取消点

时间:2015-12-20 01:54:59

标签: linux multithreading

我正在学习pthread_cancel函数并测试线程是否会在未到达取消点时被取消。线程由默认属性创建,并使其在add循环中运行。但是当发送取消请求并且线程立即退出时。它没有达到取消点,我认为它不应该立即回应请求。

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

void *thread_func(void *arg)
{
    int i;
    int j;
    int k;

    k = 1;

    /* add operation */
    for (i=0; i<1000; ++i) {       
        for (j=0; j<10000;++j) {
             ++k;              // maybe for(z=0; z<10000; ++z) added would 
                               // be better
        }
    }
    return (void *)10;
}

int main(void)
{
    char *retval;
    pthread_t tid;

    if (pthread_create(&tid, NULL, thread_func, NULL) != 0) {                 
        printf("create error\n");
    }

    if (pthread_cancel(tid) != 0) { // cancel thread
        printf("cancel error\n");
    }
    pthread_join(tid, (void **)retval); 
    printf("main thread exit\n");
    return 0;
}

2 个答案:

答案 0 :(得分:0)

要获得“取消点”,您需要使用pthread_setcancelstate()在线程函数开始时禁用取消,然后在需要时启用它。当一个新线程产生时,它具有取消状态“启用”,这意味着它可以随时立即取消。

或许更重要的是,您可能根本不应该使用pthread_cancel()。有关详情,请参阅此处:Cancelling a thread using pthread_cancel : good practice or bad

答案 1 :(得分:0)

取消线程绝不意味着它会立即取消正在运行的任何内容。它只会向该线程发布请求。 pthread_cancel仅取消取消点处的线程。取消点列表在pthreads的手册页中定义。在上面的主题中,您没有任何代码作为取消点。因此线程将始终完成,永远不会被取消。你可以增加循环或在你的线程的最后一行放一个print语句,你会发现它总是在完成线程。

但是,如果您更改以下代码以添加usleep(它是手册页中定义的取消点之一),您可以看到该线程在usleep之后终止。即使您运行任意次,线程也只会在usleep之后的取消点终止而不是任何其他点。

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

void *thread_func(void *arg)
{
    int i;
    int j;
    int k;

    k = 1;

    /* add operation */
    for (i=0; i<1000; ++i) {
        printf("Before - %d\n", i);
        usleep(1);
        printf("After - %d\n", i);
        for (j=0; j<10000;++j) {
             ++k;              // maybe for(z=0; z<10000; ++z) added would
                               // be better
        }
        printf("Never - %d\n", i);
    }
    printf("Normal Exit of thread\n");
    return (void *)10;
}

int main(void)
{
    char *retval;
    pthread_t tid;

    if (pthread_create(&tid, NULL, thread_func, NULL) != 0) {
        printf("create error\n");
    }

    usleep(1000);
    if (pthread_cancel(tid) != 0) { // cancel thread
        printf("cancel error\n");
    }
    pthread_join(tid, (void **)retval);
    printf("main thread exit\n");
    return 0;
}