【Linux】线程篇---线程控制

目录

1.多线程概念

1.1主线程

1.2 线程内部原理图

1.3多线程的共享与独有

1.4 多线程优缺点

2线程控制

2.1线程创建

2.1.1接口

2.1.2代码演示

2.2线程终止

2.2.1接口

 2.2.2代码演示

2.2.3线程的僵尸状态模拟

2.3线程等待

 2.3.1接口

2.3.2代码演示

2.4线程分离

 2.3.1接口

2.3.2代码演示


1.多线程概念

        多线程是一个进程运行时,多个线程交替并行在多个cpu执行的过程,可以提高代码执行效率。进程是操作调度的最小单位,线程是进程的最小执行单位。

        在进程阶段,我们可以通过创建子进程,然后通过进程程序替换实现同时执行多个任务,现在只使用一个进程创建出多个线程就可以达到相同的效果,且线程间切换效率更高。

1.1主线程

        之前的程序只用到一个进程,也可以称之为主线程(LWP),即main函数执行流。一般使用pid表示线程id,使用tgid表示进程组id,主线程的线程id等于进程组id。如果我们创建出多个线程,则执行main函数的线程就是主线程,其它线程我们称之为工作线程(LWF),每个工作线程都有自己的pid,一个进程的所有线程都享有一个tgid。

1.2 线程内部原理图

1.3多线程的共享与独有

        以前我们了解到一个进程有一个进程控制块(pcb),一个pcb就是一个task_struct结构体,现在我们再细化一下,创建线程时,操作系统会在pcb中加入线程的task_struct结构体。它们共享一个进程虚拟地址空间,线程之间很多资源都是共享的,这也是线程切换效率高的原因。但是不同的线程需要执行不同的代码,这也叫就意味着它们需要有部分资源是独立的,这部分资源就放在进程虚拟地址空间的共享区中。它包括调用栈,寄存器,线程id,errno,信号屏蔽字,调度优先级等。

1.4 多线程优缺点

优点

        1.多线程的程序,拥有多个执行流,合理使用,可以提高程序的运行效率。

        2.多线程程序比进程切换速度快,付出的代价小(对于共享的数据,比如全局变量可以不切换直接使用)

        3.对计算密集型数据,可以进行拆分,让不同线程执行不一样的事情。

        4.对IO密集型的程序,可以进行拆分,让不同的线程执行不同的IO操作,避免了串行操作,提高了程序运行效率。

缺点

        1.编写代码难度更高。

        2.代码稳定性要求更高,一个线程崩溃会导致整个进程崩溃

        3.缺乏访问控制,程序会产生二义性结果

        4.一个线程崩溃,可能会导致整个进程退出

2线程控制

2.1线程创建

2.1.1接口

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

//参数
thread:获取线程标识符(地址),本质上就是线程独有空间的首地址。
attr:线程的属性信息,一般填写NULL,采用默认的线程属性
//属性信息当中比较关心的:调用栈大小,分离属性,调度策略,时间片轮转,调度优先级等

start_routine:函数指针,线程执行的入口函数
arg:给线程入口函数传递参数;

返回值:
    成功:0   失败<0

作用:创建一个线程

2.1.2代码演示

  #include<stdio.h>    
  #include<unistd.h>    
  #include<pthread.h>    
      
 void* mythread(void* arg){    
      printf("i am workthread!\n");    
  }    
      int main(){    
    //创建线程    
    pthread_t tid;
    int ret= pthread_create(&tid,NULL,mythread,NULL);                                                                                                                   
     if(ret<0){    
     perror("pthread_create");    
     return 0;    
   }    
    sleep(5);    
    return 0;    
  } 

2.2线程终止

2.2.1接口

void pthread_exit(void *retval);
//参数
retval:线程退出时,传递给等待线程的退出信息

作用:谁调用谁退出

int pthread_cancel(pthread_t thread);
thread:被终止的线程标识符

作用:终止一个线程,参数传递线程标识符意味着线程可以终止非自己的线程

 2.2.2代码演示

 #include<stdio.h>    
  #include<unistd.h>    
  #include<pthread.h>    
      
  void* mythread(void* arg){    
      while(1){    
      printf("i am workthread!\n");    
      //pthread_exit(NULL);    
      }    
    }    
      
      int main(){    
      //创建线程    
    pthread_t tid;    
    int ret= pthread_create(&tid,NULL,mythread,NULL);    
     if(ret<0){    
     perror("pthread_create");    
     return 0;    
   }    
     sleep(1);                                                                                                                                                          
     pthread_cancel(tid);            /// pthred_cancel() 
     sleep(30);   
    return 0;    
  }    

2.2.3线程的僵尸状态模拟

   #include<stdio.h>    
    #include<unistd.h>    
    #include<pthread.h>         
  void* mythread(void* arg){    
      while(1){    
        printf("i am workthread!\n");                                                                                                                                   
       }    
      }    
      
        int main(){    
        //创建线程        
      pthread_t tid;    
       int ret= pthread_create(&tid,NULL,mythread,NULL);    
       if(ret<0){    
       perror("pthread_create");    
       return 0;    
     }    
      
       pthread_cancel(pthread_self());    
       while(1){    
         sleep(100);    
       }    
      
      
      return 0;    
    }    

 

2.3线程等待

 2.3.1接口

        线程在创建出来时,默认属性是joinable属性,退出的时候,依赖其它线程来回收资源(主要是退出线程使用到的共享区的空间)

int pthread_join(pthread_t thread,void ** retval);
trhread:线程标识符
retval:退出线程的退出信息
    第一种:线程入口函数代码执行完毕,线程退出的,就是入口函数返回值
    第二种:pthread

2.3.2代码演示

    #include<stdio.h>    
    #include<unistd.h>    
    #include<pthread.h>    
      
  void* mythread(void* arg){    
        printf("i am workthread!\n");        
     }                    
      int main(){        
        //创建线程        
      pthread_t tid;        
       int ret= pthread_create(&tid,NULL,mythread,NULL);        
       if(ret<0){        
       perror("pthread_create");        
       return 0;        
     }     
                                                                                                                                                                        
    pthread_join(tid,NULL);    
                                                                                                
      return 0;                                                                                 
    }  

2.4线程分离

 2.3.1接口

默认状态需要回收资源,设置分离属性就不用手动回收资源,操作系统自动进行回收。

int pthrerad_detach(pthread_t thread thread);
thread:设置分离属性的线程标识符

2.3.2代码演示

void* mythread(void* arg){
       pthred_detach(pthread_self());
       printf("i am work thread\n");                                                                                                                                    
    }        

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗二叉树_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值