参考1 https://computing.llnl.gov/tutorials/pthreads/
参考2 http://man7.org/linux/man-pages/man7/pthreads.7.htmlhtml
int pthread_join(pthread_t, void**);
阻塞调用线程,直至指定pthread_t线程终止pthread_attr_t data
typepthread_attr_init()
pthread_attr_setdetachstate()
pthread_attr_destroy()
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for(t=0; t<NUM_THREADS; t++) { printf("Main: creating thread %ld\n", t); rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); //一个attr能够给多个线程使用 if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); //记得释放资源。create执行完以后就能够释放,而不用等待线程结束
pthread_detach()
来设置线程为不可join,即便它被建立的时候被设置为joinable。这个动做不可逆pthread_attr_setstacksize
能够用来设置须要的stack大小pthread_attr_getstackaddr
和pthread_attr_setstackaddr
能够用来设置stack须要放置到特定的内存区域size_t stacksize; pthread_attr_init(&attr); pthread_attr_getstacksize (&attr, &stacksize); printf("Default stack size = %li\n", stacksize); size = 10000; //设置为10000bytes pthread_attr_setstacksize (&attr, stacksize); printf("set stack size = %li\n", stacksize); pthread_create(&threads[t], &attr, dowork, (void *)t);
//destroy,成功则返回0 int pthread_mutex_destroy(pthread_mutex_t *mutex); //动态初始化,成功则返回0. 若是attr为NULL,那么将使用默认属性,至关于PTHREAD_MUTEX_INITIALIZER int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); //使用默认参数静态初始化 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //mutex属性 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_init(pthread_mutexattr_t *attr);
pthread_mutex_init
从新初始化不能够重复初始化已经初始化了的mutexlinux
//若是别的线程已经lock,那会一直阻塞当前线程直至得到锁 int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
mutex类型 | 性质 |
---|---|
PTHREAD_MUTEX_NORMAL | 对mutex的重复lock,即本线程已经lock了mutex,在没有unlock以前又尝试lock,将致使死锁行为;unlock一个没有被本线程lock或者没有被任何线程lock的mutex,将致使未定义行为 |
PTHREAD_MUTEX_ERRORCHECK | 尝试重复lock一个mutex将不会死锁,而是返回一个错误值;unlock一个没有被本线程lock或者没有被任何线程lock的mutex,也会返回错误值 |
PTHREAD_MUTEX_RECURSIVE | mutex能够被重复lock。每次lock会增长相关计数,直至经过unlock使计数达到0时,才能够被别的线程lock;unlock一个没有被本线程lock或者没有被任何线程lock的mutex,也会返回错误值 |
PTHREAD_MUTEX_DEFAULT | 重复lock会致使未定义行为(NORMAL中会致使死锁);unlock一个没有被本线程lock或者没有被任何线程lock的mutex,也将致使未定义行为。 不过,在NDK的定义中,直接把PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL |
pthread_mutex_trylock
与pthread_mutex_lock
只有一点区别:若是当前mutex被任意线程lock,pthread_mutex_trylock
都将会马上返回。若是mutex是PTHREAD_MUTEX_RECURSIVE的,且mutex已经被当前调用线程lock,pthread_mutex_trylock
也一样会致使计数增一,并返回success。condition variable 常常和mutex一块儿使用dom
int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_condattr_destroy(pthread_condattr_t *attr); int pthread_condattr_init(pthread_condattr_t *attr);
pthread_cond_wait(), pthread_cond_timedwait(), pthread_cond_signal(), pthread_cond_broadcast(), pthread_cond_destroy()
都会产生未定义行为通常使用流程:
函数
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
pthread_cond_broadcast()
或pthread_cond_signal()
的调用都会产生调用wait的线程已经blocked on the condition variable的效果。pthread_cond_timedwait
因为超时返回以后,条件也可能已经知足。总之。任什么时候候wait返回,都须要从新评估条件是否知足,这点很是重要pthread_cond_timedwait()
和pthread_cond_wait()
是equivalent的,除了:当signaled或者broadcasted超过指定时间,pthread_cond_timedwait()
就会返回返回error。同时,cv还能够支持 Clock Selection,选择不一样的Clock来measure指定的时间int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_broadcast()
有:ui
pthread_kill
参考https://www.cnblogs.com/biyeymyhjob/archive/2012/10/11/2720377.html
---线程
pthread_t pthread_self(void);
返回调用线程的thread idrest
int pthread_equal(pthread_t t1, pthread_t t2);
比较两个ID是否相等,若是相等则返回not-zero value,不相等则返回0。因为pthread_t结果opaque,因此不该该用==
来比较code
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
:在进程中,任何首次调用这个函数的线程,在pthread_once_t once_control = PTHREAD_ONCE_INIT
的时候,会调用init_routine
程序。而且当此函数返回的时候,init_routine
已经执行完了(这里没有说init_routine
会阻塞调用线程,可能考虑的是,当线程A已经调用init_routine
,而另一个线程B也调用了pthread_once
,那么是否B也会等待A调用的init_routine
执行完毕?)。若是成功完成,则pthread_once
返回0。若是once_control
参数不是PTHREAD_ONCE_INIT
,那么行为将是undefined。在LinuxThreads中:htm
在LinuxThreads中,实际"一次性函数"的执行状态有三种:NEVER(0)、IN_PROGRESS(1)、DONE (2),若是once初值设为1,则因为全部pthread_once()都必须等待其中一个激发"已执行一次"信号,所以全部pthread_once ()都会陷入永久的等待中;若是设为2,则表示该函数已执行过一次,从而全部pthread_once()都会当即返回0。blog
这个函数在当没法编辑进程的main函数,好比写一个库的时候,就颇有用。
TODO:若是多个线程使用的init_routine
不相同怎么办?或者好比本身开发库,可是user的main中已经使用不一样的init_routine
调用了pthread_once
,那么会是什么结果?