zoukankan      html  css  js  c++  java
  • 线程相关函数(1)-pthread_create(), pthread_join(), pthread_exit(), pthread_cancel() 创建取消线程

    一. pthread_create()

    #include <pthread.h>

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

    pthread_t *thread:           传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID)
    const pthread_attr_t *attr:      
    线程属性设置,如使用默认属性,则传NULL
    void *(*start_routine) (void *):      
    函数指针,指向新线程应该加载执行的函数模块
    void *arg:            
    指定线程将要加载调用的那个函数的参数

    返回值:成功返回0,失败返回错误号。以前学过的系统函数都是成功返回0,失败返回-1,而错误号保存在全局变量errno中,而pthread库的函数都是通过返回值返回错误号,虽然每个线程也都有一个errno,但这是为了兼容其它函数接口而提供的,pthread库本身并不使用它,通过返回值返回错误码更加清晰。

    二.pthread_join()

    #include <pthread.h>
    int pthread_join(pthread_t thread, void **retval);


    pthread_t thread:        回收线程的tid
    void **retval:          接收退出线程传递出的返回值
    返回值:成功返回0,失败返回错误号

    注意:

    调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

    如果thread线程通过return返回,retval所指向的单元里存放的是thread线程函数的返回值
    如果thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED
    如果thread线程是自己调用pthread_exit终止的,retval所指向的单元存放的是传给pthread_exit的参数

    如果对thread线程的终止状态不感兴趣,可以传NULL给retval参数。

    三.pthread_exit()

    #include <pthread.h>
    void pthread_exit(void *retval);
    void *retval:      线程退出时传递出的参数,可以是退出值或地址,如是地址时,不能是线程内部申请的局部地址

    注意和exit函数的区别,任何线程里exit导致进程退出,其他线程未工作结束,主线程退出时不能return或exit。需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

    四.pthread_cancel()

    #include <pthread.h>
    int pthread_cancel(pthread_t thread);

    定义在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。可以在头文件pthread.h中找到它的定义:

    #define PTHREAD_CANCELED ((void *) -1)

    五.示例

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    
    
    void *thr_fn1(void *arg)
    {
        printf("thread 1 returning
    ");
        return (void*)1;
    }
    
    
    void *thr_fn2(void *arg)
    {
        printf("thread 2 exiting
    ");
        pthread_exit((void*)2);
    }
    
    
    void *thr_fn3(void *arg)
    {
        while(1) {
            printf("thread 3 writing
    ");
            sleep(1);
        }
    }
    
    
    int main()
    {
        pthread_t tid;
        void *retval;
    
        pthread_create(&tid, NULL, thr_fn1, NULL);
        pthread_join(tid, &retval);
        printf("thread 1 exit code %d
    ", (int)retval);    
        
        pthread_create(&tid, NULL, thr_fn2, NULL);
        pthread_join(tid, &retval);
        printf("thread 2 exit code %d
    ", (int)retval);
    
        pthread_create(&tid, NULL, thr_fn3, NULL);
        sleep(3);
        // 调用pthread_cancel函数取消第三个线程
        pthread_cancel(tid);
        // 如果线程是通过pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED
        pthread_join(tid, &retval);
        printf("thread 3 exit code %d
    ", (int)retval);
        
        return 0;
    }

    运行结果:

    thread 1 returning
    thread 1 exit code 1
    thread 2 exiting
    thread 2 exit code 2
    thread 3 writing
    thread 3 writing
    thread 3 writing
    thread 3 exit code -1

  • 相关阅读:
    共享纸巾更换主板代码分析 共享纸巾主板更换后的对接代码
    Python Django Ajax 传递列表数据
    Python Django migrate 报错解决办法
    Python 创建字典的多种方式
    Python 两个list合并成一个字典
    Python 正则 re.sub替换
    python Django Ajax基础
    Python Django 获取表单数据的三种方式
    python Django html 模板循环条件
    Python Django ORM 字段类型、参数、外键操作
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/8257655.html
Copyright © 2011-2022 走看看