线程池操作示例

None.gif 线程池
None.gif可以使用线程池来根据应用程序的需要更为有效地利用多个线程。许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生。其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态。使用线程池就可以为应用程序提供一个由系统管理的辅助线程池,从而使您可以集中精力于应用程序任务而不是线程管理。实际上,如果要执行一些需要多个线程的较短任务,则使用 ThreadPool 类是利用多个线程的最方便且最好的方法。使用线程池能够优化这些任务的执行过程,从而提高吞吐量,它不仅能够使系统针对此进程优化该执行过程,而且还能够使系统针对计算机上的其他进程优化该执行过程,即使您的应用程序对这些进程一无所知,系统也能做到这一点。使用线程池使系统能够在考虑到计算机上的所有当前进程后对线程时间片进行优化。
None.gif.NET Framework 出于以下几个目的使用线程池:异步调用、System.Net 套接字连接、异步 I
/ O 完成以及计时器与注册的等待操作等等。
None.gif通过从托管代码调用 ThreadPool.QueueUserWorkItem(或者从非托管代码调用 CorQueueUserWorkItem)并传递用来包装要添加到队列中的方法的 WaitCallback 委托来使用线程池。也可以通过使用 ThreadPool.RegisterWaitForSingleObject 并传递 WaitHandle(在向其发出信号或超时时,它将引发对由 WaitOrTimerCallback 委托包装的方法的调用)来将与等待操作相关的工作项排队到线程池中。在这两种情况下,线程池都使用或创建一个后台线程来调用回调方法。
None.gif如果您知道调用方的堆栈与在排队任务执行期间执行的所有安全检查不相关,则还可以使用不安全的方法 ThreadPool.UnsafeQueueUserWorkItem 和 ThreadPool.UnsafeRegisterWaitForSingleObject。QueueUserWorkItem 和 RegisterWaitForSingleObject 都会捕获调用方的堆栈,此堆栈将在线程池线程开始执行任务时合并到线程池线程的堆栈中。如果需要进行安全检查,则必须检查整个堆栈。尽管此检查提供了安全,但它还具有一定的性能开销。使用“不安全的”方法调用并不会提供绝对的安全,但它会提供更好的性能。
None.gif每个进程只有一个 ThreadPool 对象。线程池在您第一次调用 ThreadPool.QueueUserWorkItem 时创建,或者在一个计时器或注册的等待操作将一个回调方法排入队列时创建。一个线程监视所有已排队到线程池中的任务。当某项任务完成后,线程池中的线程将执行相应的回调方法。在对一个工作项进行排队之后将无法取消它。
None.gif可以排队到线程池中的操作的数目仅受可用内存的限制;但是,线程池将对允许在进程中同时处于活动状态的线程数目强制实施限制(这取决于 CPU 的数目和其他因素)。每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间之后创建另一个辅助线程。但线程的数目永远不会超过最大值。在执行 ThreadPool 回调时,ThreadPool 还切换到正确的 AppDomain。
None.gif在若干种情况下,适合于创建并管理自己的线程而不是使用 ThreadPool。您应在以下几种情况下创建并管理自己的线程: 
None.gif•    如果您需要使一个任务具有特定的优先级。 
None.gif•    如果您具有可能会长时间运行(并因此阻塞其他任务)的任务。 
None.gif•    如果您需要将线程放置到单线程单元中(所有 ThreadPool 线程均处于多线程单元中)。 
None.gif•    如果您需要与线程关联的永久标识。例如,您可能想使用专用线程来中止该线程、将其挂起或按名称发现它。
None.gif
None.gif
using  System;
None.gif
using  System.Threading;
None.gif
None.gif
namespace  ThreadPool6
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Class1 的摘要说明。
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    class Class1
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 应用程序的主入口点。
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        [STAThread]
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//
InBlock.gif            
// TODO: 在此处添加代码以启动应用程序
InBlock.gif            
//
InBlock.gif
    
InBlock.gif
InBlock.gif            Console.WriteLine(
"ThreadPool Test") ;
InBlock.gif            
string strSel="3";
InBlock.gif            
while(strSel.ToUpper()!="E")
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
InBlock.gif                
if(strSel.ToUpper()  =="A")
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    Console.WriteLine(
@"本示例将一个由 ThreadProc 方法表示的非常简单的任务排入队列,使用的是 QueueUserWorkItem。
InBlock.gif
") ;
InBlock.gif                    
// Queue the task.
InBlock.gif
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
InBlock.gif        
InBlock.gif                    Console.WriteLine(
"Main thread does some work, then sleeps.");
InBlock.gif                    
// If you comment out the Sleep, the main thread exits before
InBlock.gif                    
// the thread pool task runs.  The thread pool uses background
InBlock.gif                    
// threads, which do not keep the application running.  (This
InBlock.gif                    
// is a simple example of a race condition.)
InBlock.gif
                    Thread.Sleep(1000);
InBlock.gif
InBlock.gif                    Console.WriteLine(
"Main thread exits.");
InBlock.gif                    
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else if(strSel.ToUpper()=="B" )
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    Console.WriteLine(
"开始创建100个线程池对象") ;
InBlock.gif                    C_ThreadPoolTest[] cTpt
=new C_ThreadPoolTest[100] ;
InBlock.gif                    
for(int i=0;i<100;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        cTpt[i]
=new C_ThreadPoolTest(i.ToString() ) ;
InBlock.gif                        ThreadPool.QueueUserWorkItem(
new WaitCallback(cTpt[i].PrintResult ) ) ;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    Console.WriteLine(
"100个线程池对象创建完毕,主线程开始休眠 10秒钟") ;
InBlock.gif                    Thread.Sleep(
10000) ; //10秒钟
InBlock.gif

InBlock.gif                    Console.WriteLine(
"主线程休眠 10秒钟 结束") ;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else if(strSel.ToUpper()=="C")
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(
"为 QueueUserWorkItem 提供任务数据。即通过线程池可以访问到被执行类中的相关参数") ;
InBlock.gif                    
// Create an object containing the information needed
InBlock.gif                    
// for the task.
InBlock.gif
                    TaskInfo ti = new TaskInfo("This report displays the number {0}."42);
InBlock.gif
InBlock.gif                    
// Queue the task and data.
InBlock.gif
                    if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc2), ti)) 
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{    
InBlock.gif                        
//WaitCallback : 通过将 WaitCallback 委托传递给 ThreadPool.QueueUserWorkItem 来将任务排入队列以便执行。您的回调方法将在某个线程池线程可用时执行。
InBlock.gif

InBlock.gif
InBlock.gif                        Console.WriteLine(
"Main thread does some work, then sleeps.");
InBlock.gif
InBlock.gif                        
// If you comment out the Sleep, the main thread exits before
InBlock.gif                        
// the ThreadPool task has a chance to run.  ThreadPool uses 
InBlock.gif                        
// background threads, which do not keep the application 
InBlock.gif                        
// running.  (This is a simple example of a race condition.)
InBlock.gif
                        Thread.Sleep(1000);
InBlock.gif
InBlock.gif                        Console.WriteLine(
"Main thread exits.");
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        Console.WriteLine(
"Unable to queue ThreadPool request."); 
ExpandedSubBlockEnd.gif                    }

InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else if(strSel.ToUpper()=="D")
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(
@"下面的示例演示了几种线程处理功能。 
InBlock.gif1.使用 RegisterWaitForSingleObject 将需要执行的任务以 ThreadPool 线程的方式排队。 
InBlock.gif2.使用 AutoResetEvent 发出信号,通知执行任务。 
InBlock.gif3.用 WaitOrTimerCallback 委托处理超时和信号。 
InBlock.gif4.用 RegisteredWaitHandle 取消排入队列的任务。
") ;
InBlock.gif
InBlock.gif                    
// The main thread uses AutoResetEvent to signal the
InBlock.gif                    
// registered wait handle, which executes the callback
InBlock.gif                    
// method.
InBlock.gif
                    AutoResetEvent ev = new AutoResetEvent(false);  //注册等待事件
InBlock.gif

InBlock.gif                    TaskInfo2 ti 
= new TaskInfo2();
InBlock.gif                    ti.OtherInfo 
= "First task";
InBlock.gif                    
// The TaskInfo for the task includes the registered wait
InBlock.gif                    
// handle returned by RegisterWaitForSingleObject.  This
InBlock.gif                    
// allows the wait to be terminated when the object has
InBlock.gif                    
// been signaled once (see WaitProc).
InBlock.gif
                    ti.Handle = ThreadPool.RegisterWaitForSingleObject(
InBlock.gif                        ev,
InBlock.gif                        
new WaitOrTimerCallback(WaitProc),
InBlock.gif                        ti,
InBlock.gif                        
1000,
InBlock.gif                        
false   //当它为真时,只才刚开始委托处理超时和信号时执行WaitProc后面的超时将不作处理;
InBlock.gif
                        );
InBlock.gif
InBlock.gif                    
// The main thread waits three seconds, to demonstrate the
InBlock.gif                    
// time-outs on the queued thread, and then signals.
InBlock.gif
                    Thread.Sleep(3100);
InBlock.gif                    Console.WriteLine(
"Main thread signals.");
InBlock.gif                    ev.Set();
InBlock.gif
InBlock.gif                    
// The main thread sleeps, which should give the callback
InBlock.gif                    
// method time to execute.  If you comment out this line, the
InBlock.gif                    
// program usually ends before the ThreadPool thread can execute.
InBlock.gif
                    Thread.Sleep(1000);
InBlock.gif                    
// If you start a thread yourself, you can wait for it to end
InBlock.gif                    
// by calling Thread.Join.  This option is not available with 
InBlock.gif                    
// thread pool threads.
InBlock.gif

InBlock.gif                                      
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else if(strSel.ToUpper()=="W")
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Test2();
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif
InBlock.gif                Console.WriteLine(
"Please select:  A : [MsdnSample] B: [MyTestSample] C : [为 QueueUserWorkItem 提供任务数据]  D : [RegisterWaitForSingleObject用法] W : [自定义的线程RegisterWaitForSingleObject操作]  E : [Exit] ") ;
InBlock.gif                strSel
=Console.ReadLine();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// The callback method executes when the registered wait times out,
InBlock.gif        
// or when the WaitHandle (in this case AutoResetEvent) is signaled.
InBlock.gif        
// WaitProc unregisters the WaitHandle the first time the event is 
InBlock.gif        
// signaled.
InBlock.gif
        public static void WaitProc(object state, bool timedOut) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// The state object must be cast to the correct type, because the
InBlock.gif            
// signature of the WaitOrTimerCallback delegate specifies type
InBlock.gif            
// Object.
InBlock.gif
            TaskInfo2 ti = (TaskInfo2) state;
InBlock.gif
InBlock.gif            
string cause = "TIMED OUT";
InBlock.gif            
if (!timedOut) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                cause 
= "SIGNALED";
InBlock.gif                
// If the callback method executes because the WaitHandle is
InBlock.gif                
// signaled, stop future execution of the callback method
InBlock.gif                
// by unregistering the WaitHandle.
InBlock.gif
                if (ti.Handle != null)
InBlock.gif                    ti.Handle.Unregister(
null);  //取消排入队列的任务
ExpandedSubBlockEnd.gif
            }
 
InBlock.gif
InBlock.gif            Console.WriteLine(
"WaitProc( {0} ) executes on thread {1}; cause = {2}.",
InBlock.gif                ti.OtherInfo, 
InBlock.gif                Thread.CurrentThread.GetHashCode().ToString(), 
InBlock.gif                cause
InBlock.gif                );
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
static void Test2()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            C_ThreadPoolTest[] TPtest 
=new C_ThreadPoolTest[100] ;
InBlock.gif
InBlock.gif            AutoResetEvent[] startEvent 
= new AutoResetEvent[10] ;
InBlock.gif            
//通知正在等待的线程已发生事件。如果初始状态为终止状态,则为 true;否则为 false。
InBlock.gif            
//AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。
InBlock.gif            
//线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,
InBlock.gif            
//并等待当前控制资源的线程通过调用 Set 发出资源可用的信号。
InBlock.gif            
//调用 Set 终止 AutoResetEvent 以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,
InBlock.gif            
//然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。
InBlock.gif

InBlock.gif            Console.WriteLine( 
"--- 开始创建等待事件,并将其初始值设为执行 ---" ) ;
InBlock.gif            
forint i=0 ; i<10 ; i++ ) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                startEvent[i] 
= new AutoResetEvent( false ) ;
ExpandedSubBlockEnd.gif            }

InBlock.gif            Console.WriteLine( 
"--- Start creating objects ---" ) ;
InBlock.gif            
forint i=0 ; i<100 ; i++ ) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                TPtest[i]
=new C_ThreadPoolTest( i.ToString()) ;
InBlock.gif                ThreadPool.RegisterWaitForSingleObject( 
InBlock.gif                    startEvent[i
/10], 
InBlock.gif                    
new WaitOrTimerCallback( TPtest[i].PrintResult ),  //超时等待
InBlock.gif
                    null1000true ) ;  //最后一个参数设为executeOnlyOnce=false时将会对注册在进线程池中处于等待状态的线程,循环回调,没完没了.
ExpandedSubBlockEnd.gif
            }

InBlock.gif            Console.WriteLine( 
"--- Objects created ---" ) ;
InBlock.gif            Console.WriteLine( 
"--- Fire events ---" ) ;
InBlock.gif            
forint i=0 ; i<10 ; i++ ) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine( 
"终止产生的等待事件: {0}  ,以释放等待线程", i ) ;
InBlock.gif                startEvent[i].Set() ;
InBlock.gif                Thread.Sleep( 
2000 ) ;
ExpandedSubBlockEnd.gif            }

InBlock.gif            Thread.Sleep( 
2000 ) ;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif        
// This thread procedure performs the task.
InBlock.gif
        static void ThreadProc(Object stateInfo) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// No state object was passed to QueueUserWorkItem, so 
InBlock.gif            
// stateInfo is null.
InBlock.gif
            Console.WriteLine("Hello from the thread pool.");
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**/////
InBlock.gif    
InBlock.gif        
// The thread procedure performs the independent task, in this case
InBlock.gif        
// formatting and printing a very simple report.
InBlock.gif        
//
InBlock.gif
        static void ThreadProc2(Object stateInfo) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            TaskInfo ti 
= (TaskInfo) stateInfo;
InBlock.gif            Console.WriteLine(ti.Boilerplate, ti.Value); 
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
// TaskInfo contains data that will be passed to the callback
InBlock.gif        
// method.
InBlock.gif
public class TaskInfo2 
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
public RegisteredWaitHandle Handle = null;
InBlock.gif    
public string OtherInfo = "default";
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif    
public class C_ThreadPoolTest
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string ThreadName="";
InBlock.gif        
double iCount=0;
InBlock.gif        
public C_ThreadPoolTest(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ThreadName
=name;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
private double Calc( )
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
double j=0;
InBlock.gif            iCount
=0;
InBlock.gif            
for(double i=0;i<100;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                j
+=i;
InBlock.gif                
if (i%5==0)
InBlock.gif                    iCount
+=1;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return j;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public void PrintResult(object obj1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Console.WriteLine( 
"\nThread "+ThreadName+" 计算完毕.");
InBlock.gif            
double x1=Calc( );
InBlock.gif            Console.WriteLine(
"\n计算次数: "+ iCount.ToString() ) ;
InBlock.gif
InBlock.gif            Console.WriteLine(
"\n计算结果: "+  x1.ToString()); 
InBlock.gif            
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public void PrintResult(object obj1, bool bl1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Console.WriteLine( 
"\nThread "+ThreadName+" 计算完毕.");
InBlock.gif            
double x1=Calc( );
InBlock.gif            Console.WriteLine(
"\n计算次数: "+ iCount.ToString() ) ;
InBlock.gif
InBlock.gif            Console.WriteLine(
"\n计算结果: "+  x1.ToString()); 
InBlock.gif            
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
public class TaskInfo 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// State information for the task.  These members
InBlock.gif        
// can be implemented as read-only properties, read/write
InBlock.gif        
// properties with validation, and so on, as required.
InBlock.gif
        public string Boilerplate; //样板文件
InBlock.gif
        public int Value;
InBlock.gif
InBlock.gif        
// Public constructor provides an easy way to supply all
InBlock.gif        
// the information needed for the task.
InBlock.gif
        public TaskInfo(string text, int number) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Boilerplate 
= text;
InBlock.gif            Value 
= number;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
posted on 2006-03-14 14:14 DotNet编程 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/furenjun/archive/2006/03/14/349823.html

利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值