• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
zuoanddie
博客园    首页    新随笔    联系   管理    订阅  订阅

Linux之线程(day14)

一、线程的基础

二、线程的创建、退出、分离、汇合

三、线程对共享资源的访问

四、线程的同步


 以下线程皆为posix线程

一、线程的基础

进程是资源分配的基本单位,线程是执行的基本单位。

一个进程中可以有多个线程,但至少要有一个主线程。

线程共享进程资源。线程切换和线程通讯都很灵活。每个线程都有自己独有的属性。线程的ID(tid)、线程的自己栈帧、自己的信号屏蔽字(但是共享进程的信号的处理函数)

 

二、线程的创建、退出、分离、汇合

1、创建线程使用pthread_create(3),编译时需要使用pthread动态链接库(-lpthread)

头文件

  #include<pthread.h>

函数声明

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

  在当前进程创建一个新线程,新线程执行start_routine函数的代码,arg作为其唯一的参数被传递

参数:

  thread:新线程的ID

  attr:线程属性参数,需要使用pthread_attr_init(3)进行初始化,如果为NULL,则使用默认属性

  start_routine:线程的执行函数

  arg:线程执行函数的唯一的参数

返回值:

  成功:0

  错误:返回一个错误码,且*thread的内容不被定义

 例:

#include<stdio.h>
#include<pthread.h>

void *doit(void *arg){
    printf("%s\n",(char*)arg);
    return NULL;  
}
int main(void){
    pthread_t tid;
    //创建新的线程
    pthread_create(&tid,NULL,doit,"new");
    sleep(2);//防止主线程先与新线程结束,主线程休眠2s
    doit("main");
    return 0;  
}

例:如何验证一个进程具有多个线程。需要获取到进程的pid(getpid(2))和线程的tid(pthread_self(3))

头文件

#include <pthread.h>
函数原型
pthread_t pthread_self(void);
功能:
  获取调用线程的id,它的值同pthread_create(3)的第一个参数
参数:
返回值:
  总是成功返回线程的ID
#include<stdio.h>
#include<pthread.h>

void *doit(void *arg){
        pid_t pid;
    pthread_t tid;
    pid=getpid();
    tid=pthread_self();
    printf(“pid:%d\ntid:%s\n”,pid,tid);

        printf("%s\n",(char*)arg);
        return NULL;  
}
int main(void){
    pthread_t tid;
    //创建新的线程
    pthread_create(&tid,NULL,doit,"new");
    sleep(2);//防止主线程先与新线程结束,主线程休眠2s
    doit("main");
    return 0;  
}

 2、线程退出

  return和exit(3)的区别:return只是线程执行函数的结束,代表线程的结束。如果再线程函数中调用exit(3).则将会终止进程中的所有线程,故一般不会再线程中使用eixt(3)。

  如果要终止一个线程则使用pthread_exit(3):

头文件:同上

函数原型:

  void pthread_exit(void* retval);

功能;终止当前线程

参数:

  retval:退出的值存放到retval中。

返回值:

  永远不返回

 

可以使用pthreead_cancel(3)来终止其他线程。

头文件:同上

函数原型:

  int pthread_cancel(pthread_t thread);

功能:

  终止以恶指定线程

参数:

  thread:指定接收cancel请求的线程,即指定要设为canceled状态的线程。

返回值:

  成功:0

  错误:非0错误码

3,线程的汇合

  可以使用pthread_join(3)来使线程汇合,即某一线程阻塞等待另一线程,同时回收资源,以达到汇合目的。此时可以获取到线程的退出状态

头文件:同上

函数原型:

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

功能:

  线程汇合,等待指定的线程终止,如果这个指定的线程已经终止了,那么pthread_join立即返回。

参数:

  thread:指定等待的终止线程

  *retval:指定线程的退出状态(非NULL),如果这个目标线程是用pthread_cancel(3)进行终止的,那么PTHREAD_CANCELED将被保存到*retval中。

返回值:

  成功:0

  错误:错误码

4,线程分离

  线程创建之后,结束时自动回收,不作汇合,这叫做线程的分离。

  线程的分离可以视同pthread_detach(3)

头文件;同上

函数原型:int pthread_detach(pthread_t thread)

功能:

  标记thread指定的线程为detached状态,当一个处于detached状态的线程终止的时候,线程的资源将会自动回收到系统,而不是汇合的线程来进行结束。

参数:

  thread:指定设置为detached状态的线程id。

返回值:

  成功:0

  错误:错误码

例:线程的汇合

#include<stdio.h>
#include<prhead.h>

void* doit1(void *arg){
     printf("doit1 return !\n");  
     return (void*)1  
}

int main(void){
    pthread_t tid;
    void *ret;
    //创建一个线程
     pthread_create(&tid,NULL,doit1,NULL);
     //指定汇合的线程
     pthread_join(tid,&ret);
    printf("doit1 exit code%d\n",(int)ret);
    return 0;
}

 得到的退出状态就是线程函数的返回值。

例:线程退出

#include<stdio.h>
#include<prhead.h>

void* doit2(void *arg){
     printf("doit1 return !\n");  
     pthread_exit((void*)2)  
}

int main(void){
    pthread_t tid;
    void *ret;
    //创建一个线程
     pthread_create(&tid,NULL,doit1,NULL);
     //指定汇合的线程
     pthread_join(tid,&ret);
    printf("doit2 exit code%d\n",(int)ret);
    return 0;
}
#include<stdio.h>
#include<prhead.h>

void* doit3(void *arg){
    while(1)
         printf("doit3 is running !\n");  
   
}

int main(void){
    pthread_t tid;
    void *ret;
    //创建一个线程
     pthread_create(&tid,NULL,doit1,NULL);
    //给doit3发送终止请求
    pthread_cancel(tid);
     //指定汇合的线程
     pthread_join(tid,&ret);
    printf("doit3 exit code%d\n",(int)ret);
    return 0;
}

 

 

 

posted @ 2019-07-16 16:53  zuoanddie  阅读(158)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3