线程同步关于ManualResetEvent 知识

.Net技术 码拜 7年前 (2017-04-25) 1137次浏览
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Test
{
class Program
{
//默认信号为不发送状态
private static ManualResetEvent mre = new ManualResetEvent(false);

static void Main(string[] args)
{
EastWind wind = new EastWind(mre);
//启动东风的线程
Thread thd = new Thread(new ThreadStart(wind.WindComming));
thd.Start();

mre.WaitOne();//万事俱备只欠东风,事情卡在这里了,在东风来之前,诸葛亮没有进攻

//东风到了,可以进攻了
Console.WriteLine(“诸葛亮大吼:东风来了,可以进攻了,满载燃料的大船接着东风冲向曹操的战船”);
Console.ReadLine();
}
}

/// <summary>
/// 传说中的东风
/// </summary>
class EastWind
{
ManualResetEvent _mre;

/// <summary>
/// 构造函数
/// </summary>
/// <param name=”mre”></param>
public EastWind(ManualResetEvent mre)
{
_mre = mre;
}

/// <summary>
/// 风正在吹过来
/// </summary>
public void WindComming()
{
Console.WriteLine(“东风正在吹过来”);
for (int i = 0; i <= 5; i++)
{
Thread.Sleep(500);
Console.WriteLine(“东风吹啊吹,越来越近了…”);
}
Console.WriteLine(“东风终于到了”);

//通知诸葛亮东风已到,可以进攻了,通知阻塞的线程可以继续执行了
_mre.Set();
}
}

}
想问一下高手,既然是线程同步执行,那么“ mre.WaitOne();”加不加对输出结果应该是不影响的吧,原因是同步的话只能thd这个线程执行完才能执行主线程也就是  Console.WriteLine(“诸葛亮大吼:东风来了,可以进攻了,满载燃料的大船接着东风冲向曹操的战船”);,本人理解的对么?

解决方案

10

EastWind 和主线程并不是同步执行啊
所以要WaitOne
不加WaitOne的话 Main都执行完了 线程还在执行

10

引用:

本人查了很多资料说Control.Invoke通过执行指定的委托能实现UI线程和其他之间同步,这种线程同步跟上面的通过ManualResetEvent 类的例子有什么区别那?

Invoke的解释里根本就没同步这个字眼,你看到的资料都是胡扯
https://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

20

ManualResetEvent 是一种信号机制,用来阻塞当前线程。它跟主线程(或其它任意指定线程)没有直接关系,只有(你明确设计的)逻辑关系。
线程同步确实在万不得已时需要这种功能。但是从设计上看,阻塞当前线程,是很低级的所谓”同步“概念。在一个程序中,例如A改变了,引起B也改变,这叫做“事件”,使用标准的事件机制(不管事件处理程序被同步执行还是在子线程中异步执行)才是正规的做法。
有的人滥用“阻塞”机制,胡乱说什么“一个线程执行A,然后阻塞;另一个线程执行B,然后阻塞”,于是你会看到有些人胡乱写“循环+阻塞”的垃圾代码。当这种代码稍微多一点,软件性能就完蛋了、机器趋于卡死了。这就是一粒老鼠屎坏了一锅汤式的常见代码。
当一个系统中应该采取“事件驱动”的设计方式时,假如有人滥用“循环+阻塞”代码,你将来就会发现,别看好像高大上地纠结什么“线程同步”,其实是埋下来定时炸弹,是必须尽早删除的那种设计。记住,能保证基本效率的系统是事件驱动的(包括异步触发事件),而根本不是线程同步

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明线程同步关于ManualResetEvent 知识
喜欢 (0)
[1034331897@qq.com]
分享 (0)