linux高级编程(线程)(1)

虚拟地址:

线程:

        概念:线程是轻量级进程,一般是一个进程中的多个任务。
        进程是系统中最小的资源分配单位。(竞争计算机资源的最小单位)(进程能分配硬件资源,线程不行)线程是系统中最小的执行单位。


    特征:
    1、共享资源(除了栈区都共享)-->每个进程有独立的栈区,其他空间其实都用的是所从属的进程的,有效减少内存开销
    2、效率高  30%
    3、三方库: pthread  clone   posix
            3.1 编写代码头文件: pthread.h
            3.2 编译代码加载库: -lpthread   library 
            libpthread.so
            gcc 1.c -lpthread 

缺点:
    1,线程和进程相比,稳定性,稍微差些(一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程稳定。)
    2,线程的调试gdb,相对麻烦些。

线程与进程区别:
    变量开销:进程:3G(物理内存总量),线程:8M(单个程序栈的最大空间)

    资源:
        线程比进程多了共享资源。  IPC(进程间通信)
        线程又具有部分私有资源。
        进程间只有私有资源没有共享资源。
    空间:
        进程空间独立,不能直接通信。
        线程可以共享空间,可以直接通信。

线程的设计框架 

   创建多线程 --> 线程空间操作 --> 线程资源回收

线程创建:pthread_create():

int pthread_create(
        pthread_t *thread, const pthread_attr_t *attr,
        void *(*start_routine) (void *), void *arg);
    功能:该函数可以创建指定的一个线程。
    参数:thread 线程id,需要实现定义并由该函数返回。
          attr   线程属性,一般是NULL,表示默认属性。
          start_routine 指向指针函数的函数指针。
                  本质上是一个函数的名称即可。称为
                  回调函数,是线程的执行空间。

          arg  回调函数的参数,即参数3的指针函数参数。
          如果想要传多个参数:使用结构体
          返回值:成功 0
          失败 错误码

注:

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

pthread_self():

pthread_t pthread_self(void);
   功能:获取当前线程的线程id
   参数:无
   返回值:成功 返回当前线程的线程id
                 失败  -1; 

线程退出:

自行退出-->自杀-->exit()

void pthread_exit(void *retval);  //与return的效果类似
        功能:子线程自行退出
        参数: retval 线程退出时候的返回状态,临死遗言。
        返回值:无

强制退出-->他杀-->pthread_cancel()

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

pthread_join()

 int pthread_join(pthread_t thread, void **retval);    
     功能:阻塞回收。通过该函数可以将指定的线程资源回收,该函数具有
          阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
     参数:thread  要回收的子线程tid
        retval  要回收的子线程返回值/状态。-->ptread_exit(值);
     返回值:成功 0
                   失败 -1;

为什么要用ret要使用二级void指针:

因为ret期望来存储类似于函数指针,字符串(字符串使用字符数组存储)的值,这种变量本身就是一级指针,如果我们要在传参这种操作中能使被调修改主调,必须使用*运算,所以我们传进去的二级指针

期望的传参操作:

void* ret;
pthread_create(&tid,NULL,th,NULL);
pthread_join(tid,&ret); //传入一级指针地址
printf("ret %s\n",(char *)ret); //转换为需要的类型
printf("ret %d\n",*((char *)ret)); //取两次*运算

子线程的回收策略:

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

期望传回的地址:

原理:子线程退出的时候,可以返回一个内存地址
      该值所在的内存中可以存储任何数据,只要
      地址存在,则数据都可以正常返回。
    
    地址有三种:
    0、栈区变量  错误,子线程结束该地址失效。
    1、全局变量  失去意义,本质可以直接访问。

所以可以传回的地址:

    2、静态变量 
    3、堆区变量

分离属性(attribute):

设置分离属性,目的线程消亡,自动回收空间。

pthread_attr_init

int pthread_attr_init(pthread_attr_t *attr);
    功能,初始化一个attr的变量
    参数:attr,需要变量来接受初始值
    返回:0  成功,
    非0 错误

 pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr);
      功能:销毁attr变量。
      attr,属性变量
      返回:0  成功,
      非0 错误;

pthread_attr_setdetachstate

功能:把一个线程设置成相应的属性
    参数,attr,属性变量,有init函数初始化他。
    detachstate:有2个可选值,
    设置分离属性:
    PTHREAD_CREATE_DETACHED(分离线程)
    PTHREAD _CREATE_JOINABLE(非分离线程)

第二种设置分离属性的函数:pthread_deatch

int pthread_deatch(pthread_t thread);
    功能,设置分离属性
    参数,线程id号,填自己的id        

清理函数:

pthread_cleanup_push()

void pthread_cleanup_push(void (*routine)(void *), void *arg);
    功能:注册一个线程清理函数
    参数,routine,线程清理函数的入口
        arg,清理函数的参数。
    返回值,无

需要满足以下条件才会调用注册的回调函数:

1.线程被取消的时候(pthread_cancel)

2.线程主动退出的时候(pthread_exit)

3.pthread_cleanup_pop的参数为非0值(pthread_cleanup_pop)

pthread_cleanup_pop:

void pthread_cleanup_pop(int execute);
    功能:调用清理函数
    execute,非0  执行清理函数
        0 ,不执行清理
            
    返回值,无

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值