11.3 线程标识
比较线程ID是否相等 pthread_equal
获取当前线程ID,pthread_self,我觉得java中Thread.currentThread()底层调用的就是这个方法
下图中,举例:只有TID1等于线程1,那么线程1才能处理这个作业,那么其中就得用到pthread_self来获取线程1的id,然后通过pthread_equal将其与TID1比较,两者相等,线程1才能处理TID1对应的作业
11.4 线程创建
start_rtn 是线程创建以后要执行的函数,args就是传递的函数参数
pthread_create创建线程,线程id会被设置为tidp所指向的内存单元,所以id是一个地址值,其实就是一个指针,指向线程结构体pthread,看参数类型就知道
#include "apue.h"
#include <pthread.h>
pthread_t ntid;
void
printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();//线程id
printf("%s pid %lu tid %lu (0x%lx)\n", s, (unsigned long)pid,
(unsigned long)tid, (unsigned long)tid);
}
void *
thr_fn(void *arg)
{
printids("new thread: ");
return((void *)0);
}
int
main(void)
{
int err;
err = pthread_create(&ntid, NULL, thr_fn, NULL);
if (err != 0)
err_exit(err, "can't create thread");
printids("main thread:");
sleep(1);
exit(0);
}
~
~
结果如下:
root@ubun2004:/home/learnApue/apue.3e/threads# ./threadid
main thread: pid 18911 tid 140379376883520 (0x7fac9ee49740)
new thread: pid 18911 tid 140379376879360 (0x7fac9ee48700)
可以看出,tid的确是内存地址,或者说,指向线程结构的的指针
11.5 线程终止
pthread_cancel用来取消同一进程的其他线程,被取消的线程,就好像调用了pthread_exit(PTHREAD_CANCELED)一样,
谁调用了pthread_join谁就会阻塞,直到对应进程调用pthread_exit
看到了图11-3
pthread_join(threadID , returnValue)
上面两个函数,主要是为了处理线程清理程序(参数中的rtn)
pthread_exit调用以后,会执行pthread_cleanup_push,而push会执行清理函数,而pop会把上一次push建立的清理程序删除,不过需要指明的是,只有在线程调用了pthread_exit()情况下,才会执行push的处理程序,否则处理程序不执行(比如直接return 就不会执行)
11.6 线程同步
好像看到332,后面没看
11.6.7 自旋锁
自旋锁通常作为原语来实现其他类型的锁,自旋锁的初始化和反初始化函数
自旋锁的锁定和解锁函数:
11.6.8 屏障
pthread_join就是一种屏障,我们可以把屏障当成赛跑的终点,对屏障的初始化:
最后一个参数count表示,所有程序继续运行之前,必须到达屏障的线程数目
反初始化:
线程到达屏障以后,会调用wait方法,计数加1,如果此时屏障计数没有到达count,则线程休眠