惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
S
Securelist
Attack and Defense Labs
Attack and Defense Labs
T
Threat Research - Cisco Blogs
L
LINUX DO - 最新话题
The GitHub Blog
The GitHub Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
S
Security Affairs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
美团技术团队
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
O
OpenAI News
IT之家
IT之家
F
Full Disclosure
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Palo Alto Networks Blog
P
Privacy International News Feed
Webroot Blog
Webroot Blog
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
月光博客
月光博客
博客园 - 【当耐特】
N
News | PayPal Newsroom
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
The Exploit Database - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
K
Kaspersky official blog
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
博客园 - 叶小钗
TaoSecurity Blog
TaoSecurity Blog
Martin Fowler
Martin Fowler
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
D
Docker
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
PCI Perspectives
PCI Perspectives
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网

博客园 - sopper

Visual Assist X设置 转 mac入门系列教程之二–-Mac与众不同(4) 转 mac入门系列教程之二–-Mac与众不同(3) 转 mac入门系列教程之二–-Mac与众不同(2) 转 mac入门系列教程之二–Mac与众不同(1) 转 C++带有指针数组的结构体转换为C#可用的结构体 C#调用C++版本dll时的类型转换要注意的问题 小技巧 瑞星版本20.49.30的Bug C++控件的数据交换和数据校验 VC6类向导对窗体按钮添加的消息映射代码 c/c++下常见的内存错误及其对策 CORBA_TAO的环境配置 - sopper - 博客园 异步socket的线程分配(C#) 你知道main函数参数的用处吗? - sopper - 博客园 你能确定这段代码的输出结果吗? 小技巧避免项目中的大隐患 提给dudu的一个小建议 vc6使用点滴积累
再议ManualResetEvent
sopper · 2008-03-18 · via 博客园 - sopper

        ManualResetEvent就像一个信号灯,可以利用它的信号,控制当前线程是挂起状态还是运行状态。
        它有几个常用的方法:Reset(),Set(),WaitOne();
        初始化该对象时,可以指定其默认的状态(有信号/无信号);
        在初始化以后,该对象将保持原来的状态不变,直到它的Reset()或者Set()方法被调用;
        Reset()方法将其设置为无信号状态,Set()方法将其设置为有信号状态;
        WaitOne()方法在无信号状态下,可以使当前线程挂起;注意这里说的是当前线程;
        直到调用了Set()方法,该线程才被激活。

        在多线程的代码里,可以使用一个ManualResetEvent对象来控制线程所有线程;
        只要在调用WaitOne()方法前,调用Reset()方法,因为WaitOne()控制的是当前线程;
        但是这样做,ManualResetEvent对象的管理逻辑会变得复杂;
        所以这里建议一条线程一个ManualResetEvent对象。
 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleThread
{
    
class ThreadClass
    
{
        
public void threadFun()
        
{
            Thread.Sleep(
1000);
            Console.WriteLine(
"ThreadClass.threadFun 1");

            
//激活被挂起的线程
            Program.allDone.Set();

            Console.WriteLine(
"ThreadClass.threadFun 2");

            
//设置为无信号,如果注释这条语句,
            
//下面的WaitOne()方法就不起做用了
            Program.allDone.Reset();

            
//使当前线程挂起
            Program.allDone.WaitOne();

            Console.WriteLine(
"ThreadClass.threadFun 3");

        }


    }
;
    


    
class Program
    
{
        
public static ManualResetEvent allDone = new ManualResetEvent(false);
        
static void Main(string[] args)
        
{
            Console.WriteLine(
"Thread Start/Stop/Join Sample");
            ThreadClass ThreadC 
= new ThreadClass();
            Thread thread 
= new Thread(new ThreadStart(ThreadC.threadFun));
            thread.Start();

            
//挂起当前线程
            allDone.WaitOne();

            Console.WriteLine(
"Main 1");

            
//因为ThreadClass.threadFun方法里调用了Reset()
            
//所以这里的WaitOne()方法会使主线程也挂起
            
//allDone.WaitOne();

            
//使主线程挂起1秒钟,
            
//为了ThreadClass.threadFun方法里的Program.allDone.WaitOne()方法
            
//运行时间在Main()方法的allDone.Set()方法前面
            Thread.Sleep(5000);

            
//设置为有信号
            
//如果没有这条语句,ThreadClass.threadFun方法里最后一条语句就不会运行
            allDone.Set();
            Console.WriteLine(
"Main 2");
        }

    }

}