Linux线程的终止

Linux线程的终止

1.线程终止的三种情况。
  1. 线程从启动例程中简单返回(return)。
  2. 线程被同一进程中的其它线程取消。
  3. 线程调用pthread_exit()方法。
1.线程终止,并返回数据。
void pthread_exit(void *retval);
2.取消线程。
 int pthread_cancel(pthread_t thread);
3.线程清理处理程序。
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
例1.线程清理处理程序执行情况
  1. 线程从启动例程简单返回,即只return,线程清理处理程序不会执行。
  2. 线程调用pthread_exit()方法,线程清理处理程序会执行。
  3. 线程简单返回(return),pthread_cleanup_pop()中的参数为非零时,线程清理处理程序会执行。
#include 
#include 
#include 
#include 

static void cleanup_fun(void *arg){
    printf("%s: cleanup\n", (char *)arg);
}

//简单返回,return
static void *thr_fun1(void *arg){
    pthread_cleanup_push(cleanup_fun, "thread1 handler1");
    pthread_cleanup_push(cleanup_fun, "thread1 handler2");
    if(arg){
        return ((void *)1);
    }
    pthread_cleanup_pop(3);//非零时,线程清理处理程序被调用
    pthread_cleanup_pop(0);//零时,线程清理处理程序没被调用
    return ((void *)1);
}

static void *thr_fun2(void *arg){
    pthread_cleanup_push(cleanup_fun, "thread2 handler1");
    pthread_cleanup_push(cleanup_fun, "thread2 handler2");
    if(arg){
        //调用了pthread_exit(),即使pthread_ckeanup_pop()中的参数为0
        //线程清理处理程序依然执行。
        pthread_exit((void *)2);
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    pthread_exit((void *)2);
}

int main(int argc, char const *argv[])
{
    int err;
    pthread_t tid1, tid2;
    void *tret;
    err = pthread_create(&tid1, NULL, thr_fun1, (void *)0);
    if(err){
        fprintf(stderr, "th1 create %s\n", strerror(err));
        exit(err);
    }
    err = pthread_create(&tid2, NULL, thr_fun2, (void *)1);
    if(err){
        fprintf(stderr, "th2 create %s\n", strerror(err));
        exit(err);
    }
    err = pthread_join(tid1, &tret);//tret接收子线程返回的值,return返回的也能被接收
    if(err){
        fprintf(stderr, "th1 join %s\n", strerror(err));
        exit(err);
    }
    printf("th1 return code: %ld\n", (long)tret);

    err = pthread_join(tid2, &tret);
    if(err){
        fprintf(stderr, "th2 join %s\n", strerror(err));
        exit(err);
    }
    printf("th2 exit code: %ld\n", (long)tret);
    return 0;
}
执行结果:
thread1 handler2: cleanup
th1 return code: 1
thread2 handler2: cleanup
thread2 handler1: cleanup
th2 exit code: 2
例2.取消线程

执行pthread_cancel()终止线程,线程清理处理程序会被执行。pthread_join()将不会接收到线程启动例程中返回的数据。

#include 
#include 
#include 
#include 

static void clean_fun(void *arg)
{
    printf("cleanup\n");
}

static void *th_fun(void *arg)
{
    int n = 0;
    pthread_cleanup_push(clean_fun, NULL);
    while (1)
    {
        printf("n = %d\n", n++);
        sleep(1);
    }
    pthread_cleanup_pop(0);
    return (void *)3;
}

int main(int argc, char const *argv[])
{
    pthread_t tid;
    void *ret;
    int err;
    err = pthread_create(&tid, NULL, th_fun, NULL);
    if (err)
    {
        fprintf(stderr, "thread create: %s\n", strerror(err));
        exit(err);
    }
    sleep(5);
    pthread_cancel(tid);
    err = pthread_join(tid, &ret);
    if (err)
    {
        fprintf(stderr, "thread join: %s\n", strerror(err));
        exit(err);
    }
    printf("ret = %lu\n", (unsigned long)ret);
    return 0;
}
执行结果:
n = 0
n = 1
n = 2
n = 3
n = 4
cleanup
ret = 18446744073709551615//64位机的最大数,强转成int,是-1

你可能感兴趣的:(linux,c语言)