Linux——进程(3)

一、进程和线程的关系

  • 进程是程序执行和资源管理的最小单位
  • 线程是存在于进程空间的,使用的是进程资源   
  • 线程是程序执行最小单位
  • 线程  light process  //轻量级的进程 
  • 进程  heavey process //重量级的进程 
  • 进程是分配资源和调度执行的基本单位。
  • 分配资源 --- 进程 (获取系统系统资源) 
  • 调度执行 --- 线程 (侧重执行任务)
  • 线程 -系统调度的最小单位 
  • 线程因为共享进程的资源避免了大量资源的开辟 
  • 线程的创建效率 高于进程创建效率

二、进程和线程的比较

1、进程中的资源

  • pid 
  • ppid 
  • 打开的文件 
  • 虚拟地址空间 
  • code / data /bss 
  • 栈、堆 

2、线程中资源

  • tid 
  • 栈 
  • 信号 

3、线程的优缺点

pthread 线程:
    优点:

             比多进程节省资源,可以共享变量。

    概念:
            线程是轻量级进程,一般是一个进程中的多个任务。
            进程是系统中最小的资源分配单位.
            线程是系统中最小的执行单位。

    特征:
    1、共享资源
    2、效率高  30%
    3、三方库: pthread  clone   posix
            3.1 编写代码头文件: pthread.h
            3.2 编译代码加载库: -lpthread   library 
                                                 libpthread.so
                                                gcc 1.c -lpthread 
    缺点:
    1,线程和进程相比,稳定性,稍微差些  //线程间的通信 
    2,线程的调试gdb,相对麻烦些。


4、线程与进程区别

    资源:
        线程比进程多了共享资源。  
        线程又具有部分私有资源。
        进程间只有私有资源没有共享资源。
    空间:
        进程空间独立,不能直接通信。      //父进程 ---file -- 子进程 ---进程间通信 
        线程可以共享空间,可以直接通信。  // 通信方便,安全性较差,---线程间的通信(同步/互斥)
        ipc(进程间通信)

三、线程的设计框架 (posix)

  • 线程的创建  --- pthread_create
  • 线程的执行
  • 线程的退出 

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

  • 实现线程的操作 
  • 创建多线程
  • 线程空间操作
  • 线程资源回收

1、创建多线程:(NPTL)


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

           该函数可以创建指定的一个线程。
    参数:
          thread 线程id,需要实现定义并由该函数返回。
          attr   线程属性,一般是NULL,表示默认属性。(可结合性+分离属性)
          start_routine 
                指向指针函数的函数指针。
                  本质上是一个函数的名称即可。
                称为
          th 回调函数,是线程的执行空间。
          {
          }
          arg  回调函数的参数,即参数3的指针函数参数。
    返回值:

           成功 0
           失败 错误码        

注意:

  •       一次pthread_create执行只能创建一个线程。
  •       每个进程至少有一个线程称为主线程。
  •       主线程退出则所有创建的子线程都退出。 
  •       主线程必须有子线程同时运行才算多线程程序。
  •       线程id是线程的唯一标识,是CPU维护的一组数字。(NPTL(tid) ---> linux(PID))
  •       pstree 查看系统中多线程的对应关系。
  •       多个子线程可以执行同一回调函数。

四、有关线程


1.线程


  轻量级的进程 
  线程不需要太多资源
  {
    线程tid
    程序计数器  
    相关寄存器 
    栈的空间 
  }
  
线程 和 进程 关系
  1.线程是存在进程中的 
  2.线程公用了进程的各个段 和相关资源(信号,打开文件)

线程 和 进程之间 
  进程 -- 重量级的进程 --- 成为 资源分配的基本单位 
  线程 -- 轻量级的进程 --- 成为 调度执行的最小单位 


2.线程生命周期


  创建      -- pthread_create
  线程执行  -- 线程的执行函数 //(函数调用 --- 栈)
  结束      -- 


3. pthread_exit();

   主线程调用,表示主线程执行流结束,但是进程不销毁,
   等所有子进程都结束时,进程才销毁    


4、pthread_t pthread_self(void); 


   unsigned long int; %lu
   功能:获取当前线程的线程id
   参数:无
   返回值:成功 返回当前线程的线程id
                 失败  -1;


五、线程的退出


1、 自行退出   

        ==》   自杀    ==》  子线程自己退出
        exit(1);
        void pthread_exit(void *retval);
        功能:子线程自行退出
        参数: retval 线程退出时候的返回状态,临死遗言。
        返回值:无

        
2、 强制退出

        ==》  他杀    ==》  主线程结束子线程
        int pthread_cancel(pthread_t thread);
        功能:请求结束一个线程
        参数:thread 请求结束一个线程tid
        返回值:成功 0
                失败 -1;


六、线程的回收


1、线程的回收机制

                ====》不同与进程没有孤儿线程和僵尸线程。
                ====》主线程结束任意生成的子线程都会结束。
                ====》子线程的结束不会影响主线程的运行。
  int pthread_join(pthread_t thread, void **retval);    
  功能:通过该函数可以将指定的线程资源回收,该函数具有
             阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
  参数:thread  要回收的子线程tid
             retval  要回收的子线程返回值/状态。==》ptread_exit(值);
  返回值:成功 0
                失败 -1;

2、子线程的回收策略

  •   如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
  •   如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
  •   如果子线程已知必须长时间运行则,不再回收其资源。

3、线程的参数,返回值


  1)、传参数


    传整数 ===》int add(int a,int b);  //a b 形参
                         add(x,y);    //x y 实参 

        pthread_create(&tid,NULL,fun,x);

        fun  ==>  void * fun(void * arg);

    2)、传结构体

  •     定义结构体类型
  •     用结构体定义变量
  •     向pthread_create传结构体变量
  •     从fun子线程中获取结构体数据

3)、返回值

        pthread_exit(0)   ===>  pthread_exit(9);
        pthread_join(tid,NULL);   ===>  pthread_join(tid,?);
1、pthread_exit(?) ==>? = void * retval;
                          纯地址
2、pthread_join(tid,?) ==>? = void **retval;
                          地址的地址
原理:
      子线程退出的时候,可以返回一个内存地址
      改值所在的内存中可以存储任何数据,只要
      地址存在,则数据都可以正常返回。
    
地址有三种:
    0、栈区变量  错误,子线程结束该地址失效。
    1、全局变量  失去意义,本质可以直接访问。

    2、静态变量 
    3、堆区变量
      主线程通过一个地址形式的变量来接受子进程
      返回的地址变量就可以将该地址中的数据取到。


4、设置线程属性


int pthread_attr_init
int pthread_attr_destroy
int pthread_attr_setdetachstate
attached // 系 
    设置分离属性,目的线程消亡,自动回收空间。
    attribute
int pthread_attr_init(pthread_attr_t *attr);
    功能:
         初始化一个attr的变量
    参数:
         attr,需要变量来接受初始值
    返回:
          0  成功,
         非0 错误;
       
    
int pthread_attr_destroy(pthread_attr_t *attr);
      功能:销毁attr变量。
                attr,属性变量
      返回:
             0  成功,
             非0 错误;


int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    功能:把一个线程设置成相应的属性参数,attr,属性变量,有init函数初始化他。
    detachstate:有2个可选值,
    PTHREAD_CREATE_DETACHED:
            设置分离属性。
    
    第二种设置分离属性:
int pthread_detach(pthread_t thread);
    功能:设置分离属性
    参数:线程id号,填自己的id

线程退出清理函数:
void pthread_cleanup_push(void (*routine)(void *), void *arg);

    功能:注册一个线程清理函数
    参数:routine,线程清理函数的入口
              arg,清理函数的参数。
    返回值,无
        
void pthread_cleanup_pop(int execute);
    功能:调用清理函数
    execute,
            非0  执行清理函数
            0 ,不执行清理            
    返回值:无
    
触发方式:
   1.pthread_cleanup_pop(非零值)
   2.pthread_cleanup_pop(0)    //pthread_exit()    //退出动作会导致 触发 
    pthread_exit(NULL);
    pthread_cleanup_pop(0); 
   3.pthread_cancel();    //被其它线程结束时 

七、线程退出的清理函数


1.多线程程序设计 


 1).专门有个线程 
         init_system();         // ---很多资源的额申请 以及资源的初始化 
 2).负责执行处理的程序 
         do_exec(); 

 3).关机 
         cleanup_resource();         //1. 专门一个线程 ,进行资源的释放。 

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值