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;
}

 

 

 

上一篇:Java实现 LeetCode 822 翻转卡片游戏(暴力)


下一篇:com.mysql.cj.jdbc.Driver 新特性jdbc.url连接供参考