51Halcon机器视觉

 找回密码
 会员注册

QQ登录

只需一步,快速开始

扫一扫,微信登录

查看: 3298|回复: 9

[资料] C#程序线程的阻塞与异步中的同步问题

[复制链接]
  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 958 天

    连续签到: 3 天

    [LV.10]以坛为家III

    380

    主题

    1554

    帖子

    7300

    积分

    Rank: 9

    积分
    7300

    突出贡献优秀版主荣誉管理论坛元老切换助手验证会员最佳新人

    发表于 2017-9-5 22:00:06 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    .Net里提供了EventWaitHandle类来表示一个线程的同步事件。EventWaitHandle即事件等待句柄,他允许线程通过操作系统互发信号和等待彼此的信号来达到线程同步的目的。
    这个类有2个子类,分别为AutoRestEevnt(自动重置)和ManualRestEvent(手动重置)。


    下面是线程同步的几个方法:
    (1)Reset方法:将事件状态设为非终止状态,导致线程阻塞。这里的线程阻塞是指允许其他需要等待的线程进行阻塞即让含WaitOne()方法的线程阻塞;
    (2)Set方法:将事件状态设为终止状态,允许一个或多个等待线程继续。该方法发送一个信号给操作系统,让处于等待的某个线程从阻塞状态转换为继续运行,即WaitOne方法的线程不在阻塞;
    (3)WaitOne方法:阻塞当前线程,直到当前的等待句柄收到信号。此方法将一直使本线程处于阻塞状态直到收到信号为止,即当其他非阻塞进程调用set方法时可以继续执行。

    无效附件更新 权限提升操作 删帖申请 举报以及其他需要帮助请加入QQ群:214663141 广告位招商 有意者联系
  • TA的每日心情
    害羞
    2018-1-2 11:34
  • 签到天数: 21 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    16

    帖子

    531

    积分

    Rank: 6Rank: 6

    积分
    531
    发表于 2017-10-18 23:00:17 | 显示全部楼层
    多线程并发访问同一资源或变量会造成执行混乱、结果将产生不可预知的数据损坏。

    无关线程:        线程之间没有任何联系,各自独立运行,互不干扰。
    相关线程:        线程之间有联系,两个线程共享资源,等。
    临界资源:        多个线程共享的资源。
    临界区:        访问临界资源的代码
    同步:                两个线程协同工作才能共同完成一项任务的情况

    点评

    感谢你为论坛做出的go贡献!!!  发表于 2017-10-19 11:09

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-1-2 11:34
  • 签到天数: 21 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    16

    帖子

    531

    积分

    Rank: 6Rank: 6

    积分
    531
    发表于 2017-10-18 23:02:40 | 显示全部楼层
    * 终止状态:            WaitOne()允许线程访问下边的语句
             * 非终止状态:        WaitOne()阻塞线程,不允许线程访问下边的语句
             *
             * Set()方法:        把非终止状态改为终止状态用, WaitOne()允许线程访问下边的语句
             * Reset()方法:        把终止状态改为非终止状态用, WaitOne()阻塞线程,不允许线程访问下边的语句
             *
             * //true:        设置终止状态。首次不会被WaitOne()阻塞,下次执行WaitOne()才会被阻塞
             * //false:设置非终止状态。遇到WaitOne()立即阻塞所在的一个或多个线程
             *
             * AutoResetEvent are_thread = new AutoResetEvent(true);
             * //1.AutoResetEvent,调用一次Set()只能继续一个阻塞线程
             * //2.AutoResetEvent,调用Set()后自动Reset()
             *
             * ManualResetEvent mre_thread = new ManualResetEvent(false);
             * //1.ManualResetEvent,调用一次Set()允许继续全部阻塞线程,这是和AutoResetEvent的区别
             * //2.ManualResetEvent,调用 Reset(),将信号设置为非终止状态,在非终止状态线程中调用WaitOne()阻塞线程。

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-1-2 11:34
  • 签到天数: 21 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    16

    帖子

    531

    积分

    Rank: 6Rank: 6

    积分
    531
    发表于 2017-10-18 23:03:46 | 显示全部楼层
    此外,EventWaitHandle类还拥有两种模式,AutoReset 和 ManualReset 模式:
    var auto = new EventWaitHandle (false);
    var auto = new EventWaitHandle (false, EventResetMode. AutoReset);
    与AutoResetEvent类似,ManualResetEvent可以使用两种方式构造:
    var manual = new ManualResetEvent (false);
    var manual = new EventWaitHandle (false, EventResetMode.ManualReset);

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-1-2 11:34
  • 签到天数: 21 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    16

    帖子

    531

    积分

    Rank: 6Rank: 6

    积分
    531
    发表于 2017-10-18 23:09:51 | 显示全部楼层
    class Program
        {
            static ManualResetEvent _mre = new ManualResetEvent(false);

            static void Main(string[] args)
            {
                Console.WriteLine("输入1为Set()   开始运行");
                Console.WriteLine("输入2为Reset() 暂停运行");

                Thread[] _threads = new Thread[3];
                for (int i = 0; i < _threads.Count(); i++)
                {
                    _threads[i] = new Thread(ThreadRun);
                    _threads[i].Start();
                }

                while (true)
                {
                    switch (Console.ReadLine())
                    {
                        case "1":
                            Console.WriteLine("开始运行");
                            _mre.Set();                        
                            break;
                        case "2":
                            Console.WriteLine("暂停运行");
                            _mre.Reset();                        
                            break;
                        default:
                            break;
                    }
                }
               
            }

            static void ThreadRun()
            {
                int _threadID = 0;
                while (true)
                {
                    _threadID = Thread.CurrentThread.ManagedThreadId;
                    Console.WriteLine("当前线程:" + _threadID);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                    _mre.WaitOne();
                }
            }

            /*
             * 终止状态:            WaitOne()允许线程访问下边的语句
             * 非终止状态:        WaitOne()阻塞线程,不允许线程访问下边的语句
             *
             * Set()方法:        把非终止状态改为终止状态用, WaitOne()允许线程访问下边的语句
             * Reset()方法:        把终止状态改为非终止状态用, WaitOne()阻塞线程,不允许线程访问下边的语句
             *
             * //true:        设置终止状态。首次不会被WaitOne()阻塞,下次执行WaitOne()才会被阻塞
             * //false:设置非终止状态。遇到WaitOne()立即阻塞所在的一个或多个线程
             *
             * AutoResetEvent are_thread = new AutoResetEvent(true);
             * //1.AutoResetEvent,调用一次Set()只能继续一个阻塞线程
             * //2.AutoResetEvent,调用Set()后自动Reset()
             *
             * ManualResetEvent mre_thread = new ManualResetEvent(false);
             * //1.ManualResetEvent,调用一次Set()允许继续全部阻塞线程,这是和AutoResetEvent的区别
             * //2.ManualResetEvent,调用 Reset(),将信号设置为非终止状态,在非终止状态线程中调用WaitOne()阻塞线程。
             */
        }

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    窃喜
    2020-5-12 13:05
  • 签到天数: 29 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    24

    帖子

    153

    积分

    Rank: 1

    积分
    153

    活跃会员

    发表于 2018-2-1 15:32:58 | 显示全部楼层

    好东西,分享一下

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    该用户从未签到

    0

    主题

    20

    帖子

    30

    积分

    Rank: 1

    积分
    30

    热心会员

    发表于 2018-12-18 08:41:37 | 显示全部楼层
    感谢分享

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    您需要登录后才可以回帖 会员登录 | 会员注册

    本版积分规则

    建议您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流浏览器浏览本网站

    51Halcon会员技术交流会员技术交流 | 51Halcon官方客服咨询官方客服咨询 | Halcon切换助手使用反馈切换助手使用

    有问题需要咨询站长?| 申请友链| 小黑屋| 手机版| Archiver|  

    粤ICP备15095995号-2 粤公网安备44030602000670号

    CopyRight © 2015-2020 51Halcon机器视觉. Tencent Cloud X3.4.

    快速回复 返回顶部 返回列表