zoukankan      html  css  js  c++  java
  • 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
    ",(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
    tid:%s
    ”,pid,tid);
    
            printf("%s
    ",(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 !
    ");  
         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
    ",(int)ret);
        return 0;
    }

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

    例:线程退出

    #include<stdio.h>
    #include<prhead.h>
    
    void* doit2(void *arg){
         printf("doit1 return !
    ");  
         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
    ",(int)ret);
        return 0;
    }
    #include<stdio.h>
    #include<prhead.h>
    
    void* doit3(void *arg){
        while(1)
             printf("doit3 is running !
    ");  
       
    }
    
    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
    ",(int)ret);
        return 0;
    }
  • 相关阅读:
    排序算法——插入排序
    排序算法——选择排序
    排序算法——冒泡排序
    软件测试实例
    软件测试基础知识
    【数组】筛选数组arr中重复的元素,考虑时间复杂度
    【数组】最大子数组问题(要求时间复杂度最佳)
    【数组】合并两个排序数组
    【链表】循环链表插入元素
    P2668 斗地主 (NOIP 提高 2015)
  • 原文地址:https://www.cnblogs.com/ptfe/p/11136056.html
Copyright © 2011-2022 走看看