http://www.cnblogs.com/henw/archive/2012/01/06/2314870.html
C#多线程学习 之 线程池[ThreadPool]
在多线程的程序中,经常会出现两种情况:
一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应
这一般使用ThreadPool(线程池)来解决;
另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒
这一般使用Timer(定时器)来解决;
本篇文章单单讲线程池[ThreadPool]
ThreadPool类 MSDN帮助信息: http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx#Y0
将任务添加进线程池:
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名));
重载
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 参数);
因为ThreadPool是静态类 所以不需要实例化.
对于线程池主要的控制有控制线程数大小:
ThreadPool.SetMaxThreads 方法
public static bool SetMaxThreads(
int workerThreads,
int completionPortThreads
)
参数:
- workerThreads
- 类型:System.Int32
线程池中辅助线程的最大数目。
- completionPortThreads
- 类型:System.Int32
线程池中异步 I/O 线程的最大数目。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 多线程池试验 { class Program { public static void Main() { ThreadPool.SetMaxThreads(3, 3); for ( int i = 0; i < 50; i++) { thr t = new thr(); ThreadPool.QueueUserWorkItem( new WaitCallback(t.ThreadProc), i); } Console.WriteLine( "断点测试" ); Thread.Sleep(100000); Console.WriteLine( "运行结束" ); } public class thr { public void ThreadProc( object i) { Console.WriteLine( "Thread[" + i.ToString() + "]" ); Thread.Sleep(1000); } } } } |
输出结果:
您会发现 断点测试 在上面了, 这是什么原因呢?
原因:
1. 线程池的启动和终止不是我们程序所能控制的, 我反正是不知道的, 你如果知道的话 可以发邮件给我 henw@163.com
2. 线程池中的线程执行完之后是没有返回值的.
总之一句话, 我们不知道线程池他干了什么, 那么我们该怎么解决 任务完成问题呢?
操作系统提供了一种”信号灯”(ManualResetEvent)
ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。
详细见MSDN: http://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent.aspx
主要使用了
eventX.WaitOne(Timeout.Infinite, true); 阻止当前线程,直到当前 WaitHandle 收到信号为止。
eventX.Set(); 将事件状态设置为终止状态,允许一个或多个等待线程继续。
修改后的程序:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading;
namespace
多线程池试验
{
class
Program
{
public
static
void
Main()
{
//新建ManualResetEvent对象并且初始化为无信号状态
ManualResetEvent eventX =
new
ManualResetEvent(
false
);
ThreadPool.SetMaxThreads(3, 3);
thr t =
new
thr(15, eventX);
for
(
int
i = 0; i < 15; i++)
{
ThreadPool.QueueUserWorkItem(
new
WaitCallback(t.ThreadProc), i);
}
//等待事件的完成,即线程调用ManualResetEvent.Set()方法
//eventX.WaitOne 阻止当前线程,直到当前 WaitHandle 收到信号为止。
eventX.WaitOne(Timeout.Infinite,
true
);
Console.WriteLine(
"断点测试"
);
Thread.Sleep(10000);
Console.WriteLine(
"运行结束"
);
}
public
class
thr
{
public
thr(
int
count,ManualResetEvent mre)
{
iMaxCount = count;
eventX = mre;
}
public
static
int
iCount = 0;
public
static
int
iMaxCount = 0;
public
ManualResetEvent eventX;
public
void
ThreadProc(
object
i)
{
Console.WriteLine(
"Thread["
+ i.ToString() +
"]"
);
Thread.Sleep(2000);
//Interlocked.Increment()操作是一个原子操作,作用是:iCount++ 具体请看下面说明
//原子操作,就是不能被更高等级中断抢夺优先的操作。你既然提这个问题,我就说深一点。
//由于操作系统大部分时间处于开中断状态,
//所以,一个程序在执行的时候可能被优先级更高的线程中断。
//而有些操作是不能被中断的,不然会出现无法还原的后果,这时候,这些操作就需要原子操作。
//就是不能被中断的操作。
Interlocked.Increment(
ref
iCount);
if
(iCount == iMaxCount)
{
Console.WriteLine(
"发出结束信号!"
);
//将事件状态设置为终止状态,允许一个或多个等待线程继续。
eventX.Set();
}
}
}
}
}
输出结果:
顺序正常了.
程序源码: 多线程池试验.zip
http://www.cnblogs.com/henw/archive/2012/01/06/2314870.html的更多相关文章
- http://www.cnblogs.com/zhaoyang/archive/2012/01/07/2315436.html
http://www.cnblogs.com/zhaoyang/archive/2012/01/07/2315436.html
- http://www.cnblogs.com/TankXiao/archive/2012/02/06/2337728.html
http://www.cnblogs.com/TankXiao/archive/2012/02/06/2337728.html
- java解析xml汇总(转自倾城幻影-Java解析xml汇总,链接:http://www.cnblogs.com/jiugehuanying/archive/2012/01/12/2320058.html)
[引言] 目前在Java中用于解析XML的技术很多,主流的有DOM.SAX.JDOM.DOM4j,下文主要介绍这4种解析XML文档技术的使用.优缺点及性能测试. [一.基础知识--扫盲] sax.do ...
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整) 转自http://www.cnblogs.com/tiandsp/archive/2012/01/23/2329049.html
#include <windows.h> // Windows的头文件 #include <stdio.h> #include <gl\gl.h> // OpenG ...
- ESB简介及选型(转) http://www.cnblogs.com/skyme/archive/2012/08/06/2623414.html
什么是ESB 企业服务总线(Enterprise Service Bus,ESB)的概念是从面向服务体系架构(Service Oriented Architecture, SOA)发展而来的.SOA描 ...
- Centos7 systemctl和防火墙firewalld命令(参考https://www.cnblogs.com/marso/archive/2018/01/06/8214927.html)
一.防火墙的开启.关闭.禁用命令 (1)设置开机启用防火墙:systemctl enable firewalld.service (2)设置开机禁用防火墙:systemctl disable fire ...
- http://www.cnblogs.com/stephen-liu74/archive/2012/08/01/2561557.html
http://www.cnblogs.com/stephen-liu74/archive/2012/08/01/2561557.html
- http://www.cnblogs.com/Lawson/archive/2012/09/03/2669122.html
http://www.cnblogs.com/Lawson/archive/2012/09/03/2669122.html
- http://www.cnblogs.com/Matrix54/archive/2012/05/03/2481260.html
http://www.cnblogs.com/Matrix54/archive/2012/05/03/2481260.html
随机推荐
- 从有序数组中查找某个值 low_bound
二分搜索 题意: 给定长度为n的单调不下降数列a0, ...an-1和一个数k,求满足ai>=k条件的最小的i. 不存在的情况下输出n. 输入: 5 3 2 3 3 5 6 输出: ...
- Android学习笔记(24):进度条组件ProgressBar及其子类
ProgressBar作为进度条组件使用,它还派生了SeekBar(拖动条)和RatingBar(星级评分条). ProgressBar支持的XML属性: Attribute Name Related ...
- Pyqt4 360界面风格皮肤实现
前言 最近用Pyqt做了软件界面,始终觉得windows风格不太好看,虽然数字公司的行为有争议,但是也不影响我欣赏360卫士的界面风格. 声明 首先声明,此项工作并非原创,而是基于这位zhuyeqin ...
- XSS前置课程--同源策略
什么是同源策略: 在用户浏览互联网中的网页的过程中,身份和权限的思想是贯穿始终的 同源策略(Same-Origin Policy),就是为了保证互联网之中,各类资源的安全性而诞生的产物,它实际上是一个 ...
- 完好用户体验: 活用window.location与window.open解决页面跳转问题
原文地址: JavaScript Redirects and window.open原文日期: 2014年08月27日翻译日期: 2014年08月31日翻译人员: 铁锚 (译者注: 本文解决的是按 C ...
- IPv4地址(一)概述
IPv4地址的长度是多少? IPv4地址是如何表示的? IPv4地址的构成以及每一部分所起到的作用和占的位数特点? IPv4地址长度为32位. IPv4地址分为两部分:网络号和主机号 网络号部分惟一地 ...
- POJ 1787 Charlie's Change
多重背包 可行性+路径记录 题意是说你要用很多其它的零钱去买咖啡.最后输出你分别要用的 1,5 ,10 .25 的钱的数量. 多重背包二进制分解.然后记录下 这个状态.最后逆向推就可以. #inclu ...
- selenium3 踩坑--move_to_element()报错
问题:selenium3 使用move_to_element()报错,报错信息如下图所示: 网上没有找到合适的解决办法,回退到稳定的selenium2可以解决. pip install seleniu ...
- Appium python自动化测试系列之使用HTMLTestRunner生成测试报告(十三)
13.1 测试报告概述 13.1.1 测试报告的定义 在前面章节我们已经讲了自动化基础的很多东西,如果说掌握了,而且自己动手去练习了,我相信在一些初级的面试中是没任何问题的,今天我们接触的应该算是一 ...
- x86 的 TSS 任务切换机制
转自:http://blog.chinaunix.net/uid-587665-id-2732907.html [0]写在前面 segment descriptors 构建保护模式下的最基本.最根本的 ...