线程协同

本文详细介绍了线程协同的概念,包括协调器、同步对象、锁对象和等待队列等。讨论了信号量、互斥量和临界区等同步工具在控制数据一致性与资源占用中的作用。同时,阐述了 Monitor、wait/notify 机制以及 ManualResetEvent 在线程间协同中的应用,并分析了线程的五种状态和进程调度。文中强调了 Pulse 方法在等待队列到就绪队列转换中的重要性,以及不同等待时间设置的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


进程管理器:新建、就绪、等待,运行、死亡。就绪队列,等待队列。
线程管理器:新建、就绪、等待,运行、死亡。就绪队列,等待队列。线程协调(互斥量、信号信)、线程协同(等待/通知/加入尾部),队列有优先级。
线程协同工具(资源粒度、协同场景):monitor、连接,继续、autorest、多等待器,互斥、信号量。后台。
线程间传递数据:主、工作线程,传递。
进程间传递数据:ipc、rpc、共享内存,模拟文件(内存映射),文件,管道、网络、消息队列。 

================================


线程协同模块:线程,线程状态(5状,7状),行为导致状态变更,有两个辅队列(等待队列,就绪队列,每个都有消费者/供应者),控制资源访问数帮助对象(多个线程处于运行状态,处于临界区之内的数量):互斥与信号量。
数据或资源:数据
============================




工作线程:工作者

主线程:工作者

协调器:monitor(线程协同模块,只能是互斥对象),关联线程和锁对象(mutex),然后与同步对象关联的有两个队列,就绪队列、等待队列。看门大爷。提供同步访问对象的机制。

平衡工具:同步对象,锁对象 object,就绪队列、等待队列。mutex/semaphore,第三方中间资源(标记)来平衡多个工作者。

资源:数据队列,跟据线程拆分

死锁/事务/空转sleep()/wait()/通知Pulse()


====================================
同步和异步:
等待队列,就绪队列。
实现同步机制,控制数据的一致性,资源的征用/占用问题:
信号量工具:多个线程在同一时间访问同一资源的数量,计数控制器,控制数。Semaphore,限牌/总量/车位数
互斥量工具:互斥对象,作用域,线程,进程,机器,分布式锁。单转门/厕所门,资源征用。mutex/ 阀门,锁/厕所状态/停车位
临界区:串行化方式来访问的区域, 等待队列,就绪队列。等待通告或外部行为。控制区域 {},关键段。
事件:通过通知操作的方式来保持线程的同步。等待与通知工作者  wait()/notify()/Pulse()
线程间的协同,进程间的协同。多个工作者与一个或多个资源的协同。

协同:工作者协同,人员协同。
协调者,控制者,monitor,监视器
主线程,工作者
等待:轮询、通知(脉冲信号)和时间
资源的粒度:读写,内核与应用资源切换,第三方中间资源来平衡几方,更高级别资源
事务

Monitor:不关联对象,不能创建对象。
拥有锁的线程的引用。

sleep()和wait() 等通知(线程交互),等时间
与调用线程相关联。同步对象()

线程5状态:
新建:初始
就绪:就绪队列,可远行
运行:running
阻塞:等待队列,runnable,blocked(), sleep(),join(),wait()
死亡状态:正常,强制中断,运行异常

进程调度(包括:就绪队列,等待队列)

每个锁对象都有两个队列
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列

阈值:高级事务

wait/notify
wait()/Pulse()



 ManualResetEvent[] doneEvents = new ManualResetEvent[AppConfig.ThreadCount];
            for (int i = 0; i < AppConfig.ThreadCount; i++)
            {
                doneEvents[i] = new ManualResetEvent(false);
                ThreadPool.QueueUserWorkItem(new WaitCallback(MutiHtmlToPdf), doneEvents[i]);
                Thread.Sleep(1000);
            }
            WaitHandle.WaitAll(doneEvents);


         ((ManualResetEvent)obj).Set();


===============================


每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (notify)后,才会进入到就绪队列,等待获得锁


http://www.bubuko.com/infodetail-1110915.html


        执行流向:等待队列---》就绪队列---》拥有锁的线程



说来话长,先用大白话"很粗浅的"解释下这两个问题,你再去查阅相关资料就明白。

一、意义?
        首先,同步的某一个对象包含若干引用,这些引用被处于三个状态的线程队列所占据,这三个队列分别是:拥有锁的线程(处于执行中)、就绪队列(马上就可以获得锁的)、等待队列(wait中即阻塞的,需要进入就绪队列才拿到锁)。

        执行流向:等待队列---》就绪队列---》拥有锁的线程

        当拥有锁的线程执行完毕让出了锁,就绪队列的线程才有机会一窝蜂上去抢,锁只有一个,抢不到的继续在就绪队列里等待下一次机会(当然也需要考虑优先级设置情况的,没有则是这样),如此,直到 就绪队列 里的线程全部执行完。

        问题来了:等待队列 的线程如何进入 就绪队列 ,以便得到执行机会呢?

        基本途径就是:Monitor.Pulse()   或  超时自动进入。

        所以Monitor.Pulse()的意义在于:将等待队列中的下一个线程放入就绪队列。(PulseAll()则是所有)。当然,如果等待队列里是空的,则不处理Pulse。

二、如果不调用它会造成怎样的后果?
        不调用Pulse()造成的后果, 需要看等待队列中wait搜索的超时设置,即”等待的最长时间“。
        等待的最长时间有几个设置:无限期(Infinite)、某一时长、0。造成的后果由这个决定:
        1、 Infinite:无限期等待状态下,如果当前获得锁的线程不执行Pulse(),那么本线程一直处于阻塞状态,在等待队列中,得不到执行机会;
        2、某一时长:则两个情况:
            a)在该时间内,还没有超时,如果当前执行线程有Pulse(),那么本线程有机会进入就绪队列。如果当前执行线程不调用Pulse(),则本线程依然呆在等待队列;
            b)超过时长,这个线程会自动进入 就绪队列,无需当前获得锁的线程执行Pulse();
        3、0:等待时长为零,则调用wait之后的线程直接进入就绪队列而不是 等待队列。




http://zhidao.baidu.com/link?url=QDYwbKZCgjFJCx0j75fqy0w7l99NVFPOL2BuNwkgClegM4_wf-5HFPnXkPBTVqpIfFT1Luw1gmGb1s9p2holKK


http://blog.youkuaiyun.com/peter_teng/article/details/10197785

http://lavasoft.blog.51cto.com/62575/99153/


https://msdn.microsoft.com/zh-cn/library/system.threading.threadstate(v=vs.110).aspx


https://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent(v=vs.110).aspx


https://msdn.microsoft.com/zh-cn/library/system.threading.autoresetevent(v=vs.110).aspx


https://msdn.microsoft.com/zh-cn/library/system.threading.semaphore(v=vs.110).aspx


http://blog.chinaunix.net/uid-10008293-id-2972285.html

理解互斥量和信号量            


http://www.wtoutiao.com/p/i5fP3k.html



=================================
整型信号量(integer semaphore):信号量是整数
记录型信号量(record semaphore):每个信号量s除一个整数值s.value(计数)外,还有一个进程 等待队列s.L,其中是阻塞在该信号量的各个进程的标识
二进制信号量(binary semaphore):只允许信号量取0或1值
http://baike.baidu.com/view/1303265.htm

PV操作与信号量的处理相关,P表示通过的意思,V表示释放的意思。
中国读者常常不明白这一同步机制为什么叫PV操作,原 来这是狄克斯特拉荷兰文定义的,因为在荷 兰文中,通过叫passeren,释放叫vrijgeven
记录型信号量=整数变量+再个方法(pv操作)+再个队列

信号量(semaphore)的数据结构为一个值和一个 指针 ,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。

http://baike.baidu.com/link?url=sc4wm9xjwtQzn0gJREWBabIbHuGYo-0CTx1-j3iZqFEjwB1L-N63VI-ffZ0kaGD2xxpgFoY6N3ShSpyVsCneoK


http://blog.youkuaiyun.com/liushuijinger/article/details/7586656




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值