线程同步关于ManualResetEvent 知识

这个月太忙没时间看C++ 2016-10-14 02:42:13
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("诸葛亮大吼:东风来了,可以进攻了,满载燃料的大船接着东风冲向曹操的战船");,我理解的对么??
...全文
209 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 7 楼 sp1234 的回复:
ManualResetEvent 是一种信号机制,用来阻塞当前线程。它跟主线程(或者其它任意指定线程)没有直接关系,只有(你明确设计的)逻辑关系。 线程同步确实在万不得已时需要这种功能。但是从设计上看,阻塞当前线程,是很低级的所谓”同步“概念。在一个程序中,例如A改变了,引起B也改变,这叫做“事件”,使用标准的事件机制(不管事件处理程序被同步执行还是在子线程中异步执行)才是正规的做法。 有的人滥用“阻塞”机制,胡乱说什么“一个线程执行A,然后阻塞;另一个线程执行B,然后阻塞”,于是你会看到有些人胡乱写“循环+阻塞”的垃圾代码。当这种代码稍微多一点,软件性能就完蛋了、机器趋于卡死了。这就是一粒老鼠屎坏了一锅汤式的常见代码。 当一个系统中应该采取“事件驱动”的设计方式时,如果有人滥用“循环+阻塞”代码,你将来就会发现,别看好像高大上地纠结什么“线程同步”,其实是埋下来定时炸弹,是必须尽早删除的那种设计。记住,能保证基本效率的系统是事件驱动的(包括异步触发事件),而根本不是线程同步。
谢谢大神指导
  • 打赏
  • 举报
回复
事件 我们在一些刚工作的实习生那里看到了太多的胡乱任性地滥用线程(然后又胡乱“同步”)的方式,动不动就给团队的产品性能埋下定时恶性炸弹,都是这种看似有趣的“例子”给害死的!
  • 打赏
  • 举报
回复
比如说,一个正规的、设计好了系统,诸葛亮是捕获了“东风吹起”的系统时间,然后开始自己的操作的。哪里是什么阻塞“同步”概念呢?
  • 打赏
  • 举报
回复
ManualResetEvent 是一种信号机制,用来阻塞当前线程。它跟主线程(或者其它任意指定线程)没有直接关系,只有(你明确设计的)逻辑关系。 线程同步确实在万不得已时需要这种功能。但是从设计上看,阻塞当前线程,是很低级的所谓”同步“概念。在一个程序中,例如A改变了,引起B也改变,这叫做“事件”,使用标准的事件机制(不管事件处理程序被同步执行还是在子线程中异步执行)才是正规的做法。 有的人滥用“阻塞”机制,胡乱说什么“一个线程执行A,然后阻塞;另一个线程执行B,然后阻塞”,于是你会看到有些人胡乱写“循环+阻塞”的垃圾代码。当这种代码稍微多一点,软件性能就完蛋了、机器趋于卡死了。这就是一粒老鼠屎坏了一锅汤式的常见代码。 当一个系统中应该采取“事件驱动”的设计方式时,如果有人滥用“循环+阻塞”代码,你将来就会发现,别看好像高大上地纠结什么“线程同步”,其实是埋下来定时炸弹,是必须尽早删除的那种设计。记住,能保证基本效率的系统是事件驱动的(包括异步触发事件),而根本不是线程同步。
Poopaye 2016-10-14
  • 打赏
  • 举报
回复
引用 4 楼 fsdad 的回复:
我查了很多资料说Control.Invoke通过执行指定的委托能实现UI线程和其他之间同步,这种线程同步跟上面的通过ManualResetEvent 类的例子有什么区别那?
Invoke的解释里根本就没同步这个字眼,你看到的资料都是胡扯 https://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
stherix 2016-10-14
  • 打赏
  • 举报
回复
引用 3 楼 fsdad 的回复:
[quote=引用 1 楼 stherix 的回复:] EastWind 和主线程并不是同步执行啊 所以要WaitOne 不加WaitOne的话 Main都执行完了 线程还在执行
哦 谢谢 刚刚理解错了 ,我想问一下通过使用Control.Invoke 方法线程线程同步与这个ManualResetEvent 类实现,两个的区别是什么?[/quote] 这个没仔细研究过 同步效果是一样的 不过Invoke会使代码运行在主线程内,所以里面的代码可以操作UI,而ManualResetEvent同步的话,线程内访问UI是可能会出错的
  • 打赏
  • 举报
回复
引用 2 楼 shingoscar 的回复:
[quote=引用 楼主 fsdad 的回复:] 因为同步的话只能thd这个线程执行完才能执行主线程
你自己试过吗?[/quote] 我查了很多资料说Control.Invoke通过执行指定的委托能实现UI线程和其他之间同步,这种线程同步跟上面的通过ManualResetEvent 类的例子有什么区别那?
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
EastWind 和主线程并不是同步执行啊 所以要WaitOne 不加WaitOne的话 Main都执行完了 线程还在执行
哦 谢谢 刚刚理解错了 ,我想问一下通过使用Control.Invoke 方法线程线程同步与这个ManualResetEvent 类实现,两个的区别是什么?
Poopaye 2016-10-14
  • 打赏
  • 举报
回复
引用 楼主 fsdad 的回复:
因为同步的话只能thd这个线程执行完才能执行主线程
你自己试过吗?
stherix 2016-10-14
  • 打赏
  • 举报
回复
EastWind 和主线程并不是同步执行啊
所以要WaitOne
不加WaitOne的话 Main都执行完了 线程还在执行

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧