day29- 系统编程之线程

  1. 一、线程基本概念(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,相对麻烦些。 

 线程与进程区别:

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

二、多线程编写步骤

2.1 设计框架


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

                        (第一个线程叫主线程,线程平级关系)


报错:errno   strerror(errno) / perror(); 

2.2 创建多线程

     int pthread_create(
        pthread_t *thread, const pthread_attr_t *attr,
//        线程号                    属性(若为null,默认属性)
        void *(*start_routine) (void *),                     void *arg);
//  函数指针,写函数名(回调函数),线程创建成功                参数(可能需要外部传参,若不                                    
                                                               需要,则为null)


    功能:该函数可以创建指定的一个线程。


    参数:thread 线程id,需要实现定义并由该函数返回。
          attr   线程属性,一般是NULL,表示默认属性。
          start_routine 指向指针函数的函数指针。
                  本质上是一个函数的名称即可。称回调函数,是线程的执行空间。
          arg  回调函数的参数,即参数3的指针函数参数。


  返回值:成功   0
                 失败 错误码

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


    ps -eLf 查看线程相关信息Low Weigth Process
    ps -eLo pid,ppid,lwp,stat,comm

 

2.3 获取线程号

pthread_t pthread_self(void);     

            unsigned long int;         %lu


  功能:获取当前线程的线程id

  参数:无


 返回值:成功 返回当前线程的线程id
               失败  -1;
            syscall(SYS_gettid);
这个方法重启后失效
alias gcc='gcc -g -pthread '
unalias gcc 

永久起作用
cd ~ //家目录
vim .bashrc
alias gcc='gcc -g -pthread '  :wq

source .bashrc  生效

 2.4 线程的退出

    1: 自行退出 ==》自杀  ==》子线程自己退出
        exit(1);
        

void pthread_exit(void *retval); 

 exit  return p;
        功能:子线程自行退出
        参数: retval 线程退出时候的返回状态,临死遗言。
        返回值:无

            th
            {
                int a =10;

                pthread_exit(&a);
            }
            join(,&ret)


  

 2: 强制退出 ==》他杀  ==》主线程结束子线程

int pthread_cancel(pthread_t thread);

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

 三、线程的回收

3.1 线程的回收机制

不同与进程没有孤儿线程和僵尸线程。
主线程结束任意生成的子线程都会结束。
子线程的结束不会影响主线程的运行。

 3.2 线程回收函数

int pthread_join(pthread_t thread, void **retval);    

 功能:通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞


参数:thread  要回收的子线程tid
           retval  要回收的子线程返回值/状态。==》ptread_exit(值);


 返回值:成功 0,                失败 -1;

  1. 无返回值 
  2. 有返回值  

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

3.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.传字符串
        栈区字符数组:
        字符串常量:
        char *p = "hello";
        堆区字符串;
            char *pc = (char *)malloc(128);
            ptread_create(&tid,NULL,fun,pc);

            pthread_join(tid,NULL);

            free(pc);
        
            fun(void *arg)
            {
                char * pc = (char *)arg    ;
                printf("%s \n",pc);
                        %c
            }

 

3.传结构体
    1、定义结构体类型
    2、用结构体定义变量
    3、向pthread_create传结构体变量
    4、从fun子线程中获取结构体数据
 

 注意:

地址有三种:
    0、栈区变量  错误,子线程结束该地址失效
    1、全局变量  失去意义,本质可以直接访问。

解决方案:

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

 五、分离属性及线程清理函数

5.1 分离属性

设置分离属性,目的线程消亡,自动回收空间(不能再调join)。(与回收相关)

int pthread_deatch(pthread_t thread);

  功能,设置分离属性
    参数,线程id号,填自己的id

 

5.2 线程清理

同步出现:

void pthread_cleanup_push(void (*routine)(void *), void *arg);

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


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

 

process                thread
fork                pthread_create                             创建
getpid,ppid,        pthread_self                           获得号
exit,                pthread_exit                                 退出
wait,waitpid,        pthread_join                            回收
kill,                pthread_cancel                             发信号
atexit                 pthread_clean,                          清理
exec                system--->fork->exec (ls)           执行外部程序

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值