linux学习--第七天(线程)

  线程

    -线程的定义

        线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程是可以有多个线程

        多个线程共享一个进程的资源,每个线程参与操作系统的统一调度

        (可以理解为进程=进程资源+主线程+子线程

 -线程与进程

        线程与进程的区别

            内存空间

                1.一个进程中多个线程共享同一个内存空间

                2.多个进程拥有独立的内存空间

            进程/线程间通讯

                1.线程间通讯方式简单

                2.进程间通讯方式复杂

            并发操作,线程比进程更节约资源

        (联系紧密的任务在并发时优先选择多线程,如果任务之间比较独立,在并发时建议选择多多进程

-线程资源

        共享进程的资源:

            1.同一块地址空间

            2.文件描述符

            3.每种信号的处理方式(如:SIG_DFL,SIG_IGN或者自定义的信号优先级)

            4.当前工作目录

            5.用户id和组id

        独立的资源

            1.线程线

            2.每个进程都私有的上下文信息

            3.线程ID

            4.寄存器的值

            5.errno的值

            6.信号屏蔽字以及调度优先级

-线程相关的命令

        pidstat  -t  -p查看相应进程的线程

        ps  -ef | grep查看进程

        ps  -T  -p查看某个进程下所有线程

        top  -H  -p查看某一个进程下的线程

        pthread_create线程创建

            注:1.一旦子线程创建成功,则会被独立调度执行,并且与其他线程并发执行

                    2.在编译时需要链接-ipthread

        pthread_exit线程退出

            注:1.当主线程调用pthread_exit函数时,进程不会结束,也不会导致其他子线程退出

                   2.任何线程调用exit函数会让进程结束

        pthread_join阻塞调用线程

            注:1.主线程需要等待子线程退出,并释放子线程资源

        pthread_detach使线程分离

            注:线程分为可结合的可分离的

                   可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的

                  线程创建的默认状态为可结合的,可以由其他线程调用pthread_join函数等待子线程退出并释放相关资源 

            线程分离函数不会阻塞线程的执行

-创建多个线程

        创建多个线程时,一般由主线程统一创建,并等待释放资源或者分离线程,不可以递归创建

            1.多个线程如果任务相同,则可以使用同一个线程执行函数

            2.多个线程如果任务不同,则可以使用不同的线程执行函数

 -线程通讯

        线程通讯就是当多个线程共同操作共享的资源时,互相告知自己的状态以避免资源争夺

        主线程向子线程传递参数:pthread_create函数的第四个参数arg        

 子线程给主线程传递参数:

        1.在子线程将需要返回的值存储在pthread_exit函数中的retval参数中

        2.在主线程中通过pthread_join函数的第二个参数retval得到返回值,pthread_join函数会将线程的返回值(指针)保存到retval

-线程互斥锁

-关于线程互斥锁

    线程的主要优势在于能够通过全局变量来共享资源,不过这种便捷的共享是有代价的

        1.必须确保多个线程不会同时修改同一变量

        2.某一线程不会读取正由其他线程修改的变量,实际就是不能让俩个线程同时对临界区进行访问

    线程互斥锁则可以用于解决多线程资源竞争问题

    tips

        atoi函数将数字字符串转换为整数

-线程互斥锁

    线程互斥锁工作机制

        当线程A获得锁,另外一个线程B在获得锁是则会阻塞,直到线程A释放锁,线程B才会获得锁

    线程互斥锁工作原理

        本质上是一个pthread_mutex_t类型的变量,假设名为V

            当V=1表示当前临界资源可以被竞争访问

            当V=0表示当前临界资源正在被某个线程访问,其他线程需要等待

    线程互斥锁的特点

        1.一个pthread_mutex_t类型的变量,就代表一个互斥锁

        2.如果俩个线程访问的是同一个pthread_mutex_t变量,那么他们访问了同一个互斥锁

        3.对应的变量定义在pthreaddtypes.h头文件中,是一个共用体包含一个结构体

    线程互斥锁的初始化

        静态初始化pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER

        动态初始化:

            pthread_mutex_init函数初始化线程互斥锁

            pthread_mutex_destroy函数销毁线程互斥锁

    线程互斥锁的操作

        线程互斥锁的操作主要分为获取锁释放锁

            pthread_mutex_lock函数获取锁的函数

            pthread_mutex_unlock函数释放锁的函数

-线程同步

    -线程同步的概念

        线程同步:是指在互斥的基础上,通过其他机制实现访问者对资源的有序访问

        条件变量:线程库提供专门针对线程同步的机制

        线程同步比较典型的应用场合就是生产者和消费者

    -生产者与消费者模型原理

        在这个模型中,包括生产者线程和消费者线程,通过线程来模拟多个线程同步的过程

            这个模型中,需要以下组件:

                1.仓库:用于存储产品,一般作为共享资源

                2.生产者线程:用于生产产品

                3.消费者线程:用于消费产品

        原理:

                1.当仓库没有产品时,则消费者线程需要等待,直到有产品时才能消费

                2.当仓库已经装满产品时,则生产者线程需要等待,直到消费者线程消费产品之后才会生产(轮询是否有产品可以消费,非常消耗CPU资源

 

-条件变量

     条件变量:允许一个线程就某个共享变量的状态通知其他线程,并让其他线程等待这一通知

-条件变量的初始化

    静态初始化 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    动态初始化:

        pthread_cond_init函数初始化条件变量

        pthread_cond_destory函数销毁条件变量

    -条件变量原理

        

step 1 :

    消费者线程判断消费条件是否满足(仓库是否有产品),如果有产品则可以消费,然后解锁
step 2 :

    当条件满足仓库产品数量为0时,调用pthread_cond_wait函数,这个函数做的事情如下:

        1.在线程睡眠之前,对互斥锁解锁

        2.让线程进入到睡眠状态

        3.等待条件变量收到信号时,该函数重新竞争锁,并获取锁
step 3 :

    重新判断条件是否满足,如果满足,则继续调用pthread_cond_wait函数
step 4 :

    唤醒后,从pthread_cond_wait返回,条件不满足,则正常消费产品
step 5 :

    释放锁,整个过程结束

    pthread_cond_wait函数阻塞线程,等待唤醒

      tips:

        1.条件变量需要与互斥锁结合使用,先获得锁才能进行条件变量的操作

        2.调用函数后会释放锁,并阻塞线程

        3.一旦线程唤醒,需要重新竞争锁,重新获得锁之后,pthread_cond_wait函数返回

    pthead_cond_signal函数唤醒所有阻塞在某个条件变量上的线程(主要适用等待线程都在执行完全相同的任务)

    pthread_cond_broadcast函数唤醒所有阻塞在某个条件变量上的线程(主要适用等待线程都执行不相同的任务)

    (条件变量并不保存状态信息,条件变量代表时一个通讯机制

-问题

    1. 为什么条件变量需要与互斥锁结合起来使用?

        答:防止在调用 pthread_cond_wait 函数等待一个条件变量收到唤醒信号,另外一个线程发送信号在一个线程实际等待它之前,也就是说线程还没有完全进入到睡眠状态,其他线程发送唤醒信号

    2.在判断条件时,为什么需要使用 while(number == 0),而不是 if()?

        答:防止虚假唤醒

            能够唤醒的情况如下:

                1.被信号唤醒,并非由条件满足而唤醒

                2.条件变量状态时,一次唤醒多个线程,但是被其他线程先消费玩产品,等到当前线程执行时,条件已经不满足

        

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值