pthread学习笔记(二)--pthread常用API及简单介绍

    技术2022-05-20  55

    经过了上篇文档的初步学习,对pthread有了一个简单的感性认识,但是对pthread的认识还是比较少,在这篇文档当中将要主要学习pthread的一些常用的API。

     

    首先是pthread的线程创建API: pthread_create

    #include<pthread.h> int pthread_create(pthread_t *thread,//要创建的线程 pthread_attr_t *attr,//线程的相关属性 void* (*start_routine)(void*),//线程要执行的函数指针 void *arg//传递给start_routine的参数 ); 

    当创建函数执行成功的时候返回0,并把创建的线程tid写入传入的线程指针中去(第一个参数),否则返回一个非零值并设置errno。

    其中,第一个和第三个参数是必须要设置的,其他两个参数可以根据情况设置,当没有需求的时候传入NULL即可。

     

     

    pthread_exit: 终止当前线程

     

    #include<pthread.h> void pthread_exit(void *retval); //该函数用于退出当前线程,退出之前将调用pthread_cleanup_push //上述函数将在下文中介绍。 //该函数在线程的上层函数中是被隐式调用的,可以增加一个retval参数 //显示调用,以供pthread_join函数参考

     

    pthread_join:挂起当前线程直到指定的线程终止为止(这个函数对于pthread十分重要,正如上一篇文档中所说的,不调用该函数可能会造成后续的create失败的问题)。

    #include<pthread.h> int pthread_join(pthread_t thread, void **thread_return); //thread_return为th终止时的参数, //没有显式指定则为NULL //需要查阅该参数的使用方法

     

    pthread_cancel: 撤销一个线程

    #include<pthread.h> //撤销线程thread int pthread_cancel(pthread_t thread); //用于设置当前线程的撤销状态 //PTHREAD_CANCEL_ENABLE允许撤销 //PTHREAD_CANCEL_DISABLE忽略撤销 //为了避免被另外的线程用pthread_cancel撤销 //oldstate用来保存之前的状态,以便恢复 int pthread_setcancelstate(int state, int *oldstate); //设置当前线程的撤销类型,包括: //PTHREAD_CANCEL_ASYNCHRONOUS立即撤销 //PTHREAD_CANCEL_DEFERRED 延迟至撤销点 int pthread_setcanceltype(int type, int *oldtype);

     

     

    线程属性:(上文中create函数的第二个参数,类型为pthread_attr_t,可以使用pthread_attr_XXXX函数族调用)

     

    detachstate:分离或者切入状态,有两个值PTHREAD_CREATE_JOINABLE(default value),PHTREAD_CREATE_DETACHED

     

    schedpolicy:  调度策略,取值有: SCHED_OTHER, SCHED_FIFO

     

    schedparam:  调度策略相关

     

    inheritsched: PTHREAD_EXPLICIT_SCHED(default value), PTHREAD_INERIT_SCHED

     

    scope: 时间片,取值有:PTHREAD_SCOPE_SYSTEM(default value每个线程 一个系统时间片), PTHREAD_SCOPE_PROGCESS(线程共享系统时间片)。

     

     

    pthread cleanup宏

     

    pthread cleanup宏主要用来处理线程的推出状态,pthread_exit和pthread_join等可以作为它的参数

    #include<pthread.h> //这些都是宏定义,相关细节可以查看/usr/include/pthread.h void pthread_cleanup_push( void(*routine)(void*), void *arg); void pthread_cleanup_pop(int execute); void pthread_cleanup_push_defer_np(void(*routine)(void*), void *arg); void pthread_cleanup_pop_restore_np(int execute); //对这些宏的理解并不深入,在后续的学习中参考相应的例子 //进一步的学习。 //这些宏用于线程结束时释放相关资源,用pthread_exit调用pthread_cleanup //进行处理时,用完后要用对应的pthread_cleanup_pop从栈中弹出

     

    互斥mutex

    由于线程是并发执行的,因此有时候需要对一些数据进行保护,例如多线程标准输出如果不加以处理,那么输出基本上都会是乱码,此时就可以使用mutex对输出流进行控制,一个线程执行写入操作的时候,加一把互斥锁,以防别的线程同时写入。

     

    互斥对象在pthread中的定义为pthread_mutex_t,以下是它的一些API函数:

    #include<pthread.h> //创建互斥对象,用指定的初始化属性初始化互斥对象 //属性包括: //PTHREAD_MUTEX_INITIALIZER 快速互斥,简单加解锁 //PTHREAD_RECURSIVE_MUTEX_INITIALIZER //递归互斥,给加锁计数,解锁时需要同样次数的pthread_mutex_unlock //PTHREAD_ERRORCHECK_MUTEX_INITIALIZER //创建检错互斥,这种互斥在被锁之后会试图给它加锁的线程返回一个 //EDEADLK错误代码而不阻塞 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr); //加锁 int pthread_mutex_lock(pthread_mutex_t *mutex); //解锁 int pthread_mutex_unlock(pthread_mutex_t *mutex); //加锁,但是如果对象已经上锁则返回EBUSY错误代码而不阻塞 int pthread_mmutex_trylock(pthread_mutex_t *mutex); //析构并释放mutex相关资源 int pthread_mutex_destroy(pthread_mutex_t *mutex); //以上的函数成功均返回0,和一般的函数一致

     

    条件变量

    线程使用条件变量对象来阻塞自己以等待某个特定条件的发生。

    条件对象的定义为pthread_cond_t

    #include<pthread.h> //创建指向条件变量的指针,在linux下可以使用PTHREAD_COND_INITIALIZER pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); //析构 int pthread_cond_destroy(pthread_cond_t *cond); //两个信号函数 int pthread_cond_singal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); //两个等待条件否则挂起的函数 //当前期望的条件没有到来的时候挂起线程,解锁mutex //条件成立的时候唤起线程,锁定互斥 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); //abstime参数和兼容time()返回值的绝对时间, //UNIX纪元时间1970-01-01起至今的秒数 //如果该时间前条件未发生,则结束并返回ETIMEOUT错误 int pthread_cond_wimewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); //上述两个函数都将被设置为撤销点(这个撤销点的意义?)

     

    至此,基本的pthread的API函数就学习到这里了,在后续的学习当中,将会结合例子更深入的学习。

     


    最新回复(0)