一、线程概念

  我个人理解线程,说简单点,是程序的一个控制流程,从代码的角度来看,它控制着一个函数的执行;

  说复杂点,在linux下,它就是一个进程(仅限linux),因为在linux下对于线程并没有特别的数据结构去描述它.

  简而言之,线程是代码的一个执行流.

二、线程与进程的区别

  线程与进程的区别,足够再写一篇博客了,在这里,我总结一下(夹杂着多线程与多进程的区别):

  1.线程强调的是资源共享,因为与主线程共享PCB;进程强调的是独立性,因为每个独立的进程有各自独立的PCB.

  2.也正因为如此,创建一个线程的开销要比创建进程的开销要小.

  3.多线程程序,只要有一个线程出现异常,其他线程都会被"诛连",导致程序异常出错.多进程程序,各进程之间独立,不会彼此影响.

三、线程控制

  因为线程不属于系统调用,因此需要用到pthread.h库

  1.创建线程

#include <pthread.h>
int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);
//thread:线程id,返回型参数
//attr:线程属性
//start_routine:所要执行的的函数(返回值void*,参数为void*)
//arg:函数的参数

  2.终止线程

  有三种方法可以终止一个线程:

  a.通过return返回,对主线程不适用.

  b.一个线程可以调用pthread_cancel终止其它线程.

  c.调用pthread_exit终止自己.

void pthread_exit (void*retval);
//retval:返回值,可以返回给pthread_join函数

  3.线程等待

  根据线程的终止情况不同,pthread_join有以下三种情况:

  a.如果线程通过return返回,则retval中存放线程的返回值

  b.如果线程被异常终止,则retval中存放的是PTHREAD_CANCELED.

  c.如果线程通过pthread_exit终止,则retval中存放的是pthread_exit的参数.

int pthread_join(pthread_t pthread,void **retval);
//pthread:需要等待的线程id
//retval:带回的参数
//成功返回0,失败返回错误号

  4.线程的分离与结合

  对于任意时间点,线程都是可分离的或者可结合的.

  可结合的线程可以被其他线程收回资源或者杀死,在其他线程回收资源之前,它的资源是不会被释放的.

  可分离的线程不能被其他线程回收或杀死,其资源是自动释放的.

  默认情况下,线程都是可结合的.

  如果一个可结合的线程运行完毕,没有被其他线程回收资源,那么它就会导致类似于僵尸进程的情况.

  当有线程调用pthread_join回收其它线程时,如果其他线程没有运行结束,则调用者会阻塞,为了避免这种情况,我们可以将该线程分离出去.

  分离线程需要调用:

int pthread_detach(thread_id);    //一般是分离自己pthread_detach(pthread_self);

  这样的话,就不必主线程去回收其资源,该线程运行完毕,会自动释放所有的资源.