• 一篇带你完全掌握线程的博客


      前言:最近一直在疯狂学习,之前也不太了解线程,现在基本都掌握了。如果你之前也不知道线程,也不知道进程和线程的区别等等,这一篇博客带你完全掌握,不掌握不要钱,哈哈哈!

      一、线程概念

       介绍概念之前,先画个图吧,依旧是全博客园最丑图,不接受反驳!

      

      

      简单说明一下:进程在其内部创建线程,线程有自己的PCB,但没有独立的地址空间。

      线程和进程具有以下特征和区别:

      LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下)

      进程:独立地址空间,拥有PCB

            线程:也有PCB,但没有独立的地址空间(共享)

            区别:在于是否共享地址空间。         独居(进程);合租(线程)。

            Linux下:          线程:最小的执行单位(CPU分配时间轮片是通过线程来实现的)

                                        进程:最小分配资源单位,可看成是只有一个线程的进程

      参考:《Linux内核源代码情景分析》 ----毛德操

      二、线程共享资源  

        1.文件描述符表

             2.每种信号的处理方式

             3.当前工作目录

             4.用户ID和组ID

             5.内存地址空间 (.text/.data/.bss/heap/共享库)

      三、线程非共享资源

       1.线程id

             2.处理器现场和栈指针(内核栈)

             3.独立的栈空间(用户空间栈)

             4.errno变量

             5.信号屏蔽字

             6.调度优先级

      四、线程的优缺点

        优点:     1. 提高程序并发性        2. 开销小        3. 数据通信、共享数据方便

             缺点:     1. 库函数,不稳定        2. 调试、编写困难、gdb不支持          3. 对信号支持不好

             优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大。

      五、线程相关函数

      在学习线程函数之前,再说点题外话。类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。所以可以将线程相关函数与进程函数进行对比学习。

    •   pthread_self函数

      功能:获取线程ID。其作用对应进程中 getpid() 函数。

      原型:pthread_t pthread_self(void);

      返回值:成功:0;       失败:无!

      线程ID:pthread_t类型,本质:在Linux下为无符号整数(%lu),其他系统中可能是结构体实现

           线程ID是进程内部,识别标志。(两个进程间,线程ID允许相同)  

    •   pthread_create函数 

       功能:创建一个新线程。                   其作用,对应进程中fork() 函数。

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

      返回值:成功:0;       失败:错误号         -----Linux环境下,所有线程特点,失败均直接返回错误号。

      参数说明:

      pthread_t:当前Linux中可理解为:typedef  unsigned long int  pthread_t;

      参数1:传出参数,保存系统为我们分配好的线程ID

           参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。

           参数3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。

           参数4:线程主函数执行期间所使用的参数。跟参数三关联。

      注意:链接线程库 -lpthread

      写一个简单程序,演示这两个函数用法:

      

    #include<stdio.h>
    #include<unistd.h>
    #include<pthread.h>
    
    void *tfn(void *arg)
    {
        printf("child thread%lu
    ",pthread_self());
        return NULL;
    }
    
    int main()
    {
        pthread_t tid;
        pthread_create(&tid,NULL,tfn,NULL);
        sleep(1);
        printf("main thread:%lu
    ",pthread_self());
        
        return 0;
    }
    View Code

      编译:gcc pthread_cre.c -lpthread,记得链接线程库 -lpthread

    •    pthread_exit函数

      功能:将单个线程退出 相当于exit

      原型:void pthread_exit(void *retval);

      参数:retval表示线程退出状态,通常传NULL

    •   pthread_join函数

      功能:阻塞等待线程退出,获取线程退出状态              其作用,对应进程中 wait()、waitpid() 函数。

      原型:int pthread_join(pthread_t thread, void **retval);

      参数:thread:线程ID (【注意】:不是指针);retval:存储线程结束状态。

    •   pthread_detach函数

      功能:实现线程分离 线程独有的,没有进程的相关函数与之对应

      原型:int pthread_detach(pthread_t thread);

      线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络、多线程服务器常用。

      重点:分离状态的线程就不需要回收了!!!重要的事情说三遍,三遍,三遍!!!

    •   pthread_cancel函数

      功能:杀死(取消)线程                         其作用,对应进程中 kill() 函数。

      原型:int pthread_cancel(pthread_t thread);

      【注意】:线程的取消并不是实时的,而有一定的延时。需要等待线程到达某个取消点(检查点)。

       六、控制原语对比

      就是就是将进程相关函数与线程函数,进行对比来记忆:

      进程                        线程

         fork                     pthread_create

         exit                     pthread_exit

         wait                    pthread_join

         kill                       pthread_cancel

         getpid                pthread_self              

      总结:欢迎评论,交流与学习。

      

  • 相关阅读:
    JavaScript高级程序设计(第2版)笔记 数据类型
    javascript中的继承[三] 基于对象(《ObjectOriented JavaScript》第六章)
    关于Table的边距问题
    centos7安装rabbitmq(干货)
    该文件内的类不是从可进行可视化设计的类继承,因此 Visual Studio 无法为该文件打开设计器
    关于水晶报表的其他说明
    HTTP错误代码大全【转自百度百科】
    关于OperationContext类
    C# 与 SQLite 的使用
    NHibernate 常见问题整理
  • 原文地址:https://www.cnblogs.com/liudw-0215/p/9682962.html
Copyright © 2020-2023  润新知