一 Linux--多线程( 六 )

一 Linux--多线程
文章插图
主线程把子线程谋杀了 , 只能取消同一个进程中的线程 , 还可以根据count的值看出 , 每个线程有自己独立的PCB , 在PCB中存在自己的栈区 。
线程等待线程等待的原因:

  • 已经退出的线程 , 其空间没有被释放 , 仍然在进程的地址空间内 。
  • 创建新的线程不会复用刚才退出线程的地址空间 。
int pthread_join(pthread_t thread, void **retval);功能:    等待线程结束(此函数会阻塞) , 并回收线程资源 , 类似于进程的wait()函数 。如果线程已经结束 , 那么该函数会立刻返回 。参数:    thread:被等待的线程号    retval:用来存储线程退出状态的指针的地址返回值:     成功:0     失败:非0#include <stdio.h>#include <pthread.h>#include <unistd.h>long retval = 10;void* pthreadrun(void* arg){  int count = 0;  while (1){    printf(" new threaad is running, pid is %d, thread id is %p\n", getpid(), pthread_self());    sleep(1);    if (++count == 3){      pthread_exit((void*)retval);    }  }}int main(){  pthread_t thread;  pthread_create(&thread, NULL, pthreadrun, NULL);  printf("main thread is waiting new thread\n");  void* ret = NULL;  pthread_join(thread, &ret);  printf("new thread has exited, exit code is %ld\n", (long)ret);  return 0;}运行结果如下:
一 Linux--多线程

文章插图
pthread_join函数会阻塞主线程 , 只有等待线程执行完毕线程处理函数之后 , 才会继续执行主进程 。
总结:
  • 如果thread线程通过return返回 , retval所指向的单元里存放的是thread线程函数的返回值 。
  • 如果thread线程被别的线程调用pthread_ cancel异常终掉 , retval所指向的单元里存放的是常数PTHREAD_CANCELED(-1) 。
  • 如果thread线程是自己调用pthread_exit终止的 , retval所指向的单元存放的是传给pthread_exit的参数 。
  • 如果对thread线程的终止状态不感兴趣 , 可以传NULL给retval参数 。
线程分离为了解决线程阻塞的问题 , 提出了线程分离 , 防止因为阻塞而造成的资源浪费 。
  • 一般情况下 , 线程终止后 , 其终止状态会一直保留到其他线程调用pthread_join获取它的状态为止 。但是线程也可以被设置成detach状态 , 这样的线程一旦中止就立刻回收它占有的所有资源 , 而不保留终止状态 。
  • 不能对一个已经处于detach状态的线程调用pthread_join , 这样的调用将返回EINVAL错误 。也就是说 , 如果已经对一个线程调用了pthread_detach就不能再调用pthread_join了 。
int pthread_detach(pthread_t thread);功能: 使调用线程与当前进程分离 , 分离后不代表不依赖当前线程 , 线程分离的目的是将资源回收的工作交给系统来处理 , 也就说当被分离的线程结束之后 , 系统将自动回收它的资源 , 所以此函数不会阻塞 , 由内核自动完成线程资源的回收 , 不再阻塞参数: thread:线程号返回值: 成功:0 失败:非0

经验总结扩展阅读