线程函数汇总

返回当前线程的线程ID`

pthread_t pthread_self(void);    

创建线程

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

重要结论:在没有人为干预的情况下,虚拟地址空间的生命周期和主线程是一样的,与子线程无关。如果要让子线程执行完毕,主线程在推出,可以在主线程中添加sleep()

线程退出

作用:终止线程,并返回结果。

void pthread_exit(void *retval);

回收子线程数据

如果还有子线程在运行,调用该函数就会阻塞,子线程退出函数解除阻塞进行资源的回收,函数被调用一次,只能回收一个子线程,如果有多个子线程则需要循环进行回收。

int pthread_join(pthread_t thread, void **retval);
  • 使用子线程栈:如果多个线程共用同一个虚拟地址空间,每个线程在栈区都有一块属于自己的内存,相当于栈区被这几个线程平分了,当线程退出,线程在栈区的内存也就被回收了,因此随着子线程的退出,写入到栈区的数据也就被释放了。

  • 使用全局变量:位于同一虚拟地址空间中的线程,虽然不能共享栈区数据,但是可以共享全局数据区堆区数据,因此在子线程退出的时候可以将传出数据存储到全局变量、静态变量或者堆内存中。

  • 使用主线程栈:虽然每个线程都有属于自己的栈区空间,但是位于同一个地址空间的多个线程是可以相互访问对方的栈空间上的数据的。由于很多情况下还需要在主线程中回收子线程资源,所以主线程一般都是最后退出,基于这个原因在下面的程序中将子线程返回的数据保存到了主线程的栈区。

线程分离

问题:在某些情况下,程序中的主线程有属于自己的业务处理流程,如果让主线程负责子线程的资源回收,调用pthread_join() 只要子线程不退出主线程就会一直被阻塞,主要线程的任务也就不能被执行了。

解决:在线程库函数中为我们提供了线程分离函数 pthread_detach(),调用这个函数之后指定的子线程就可以和主线程分离,当子线程退出的时候,其占用的内核资源就被系统的其他进程接管并回收了。线程分离之后在主线程中使用 pthread_join() 就回收不到子线程资源了。

int pthread_detach(pthread_t thread);

线程取消

线程取消的意思就是在某些特定情况下在一个线程中杀死另一个线程。使用这个函数杀死一个线程需要分两步:

  1. 在线程 A 中调用线程取消函数 pthread_cancel,指定杀死线程 B,这时候线程 B 是死不了的。

  2. 在线程 B 中进程一次系统调用(从用户区切换到内核区),否则线程 B 可以一直运行。

线程ID比较

返回值:如果两个线程 ID 相等返回非 0 值,如果不相等返回 0

int pthread_equal(pthread_t t1, pthread_t t2);