. Net multi-thread programming

Source: Internet
Author: User
Basic concepts of threads

• A thread is the basic atomic unit of program execution. A process can be composed of multiple threads.

• Each thread maintains the exception handling program, scheduling priority, and a group of systems used to save the thread context structure before scheduling the thread. The thread context includes all the information required for the thread to seamlessly continue execution in the host process address space of the thread, including the CPU register group and stack of the thread.

• In distributed programming, correct use of threads can improve the performance and running efficiency of applications. the implementation principle is to divide a process into multiple threads and then let them execute concurrently and asynchronously to improve the running efficiency.

• Concurrent execution is not performed at the same time (occupying the CPU). At any time, only one thread can occupy the CPU, But they compete for the CPU more frequently and feel that they are all running.

When to use a thread?

• Generally, if multiple threads need to seize one or more resources during execution, it is best not to use Asynchronous threads for execution. because they are executed concurrently, it is very likely to compete for a resource with a CPU at the same time. In this case, either the resource allocation algorithm is executed (for example, it takes time to determine which thread has a high priority ), or the time slice algorithm (this requires the time required to poll the CPU/hand over/let out the CPU ).

• If the system resources required by multiple threads are relatively uniform, they can be executed asynchronously and concurrently,

Disadvantages of using threads

• The memory will be used for context information required by processes and threads. Therefore, the number of processes, appdomain objects, and threads that can be created is limited by the available memory.

• Tracking a large number of threads will take a lot of processor time. If there are too many threads, most of them will not produce significant progress. If most of the current threads are in one process, the scheduling frequency of the threads in other processes will be very low.

• Using many threads to control code execution is complex and may produce many errors.

• To destroy a thread, you must understand the possible problems and handle them.

Thread Pool

• Threads created by many applications consume a lot of time in the sleep state to wait for an event to occur. This will waste resources.

• The thread pool allows you to use threads more effectively by providing an auxiliary thread pool managed by the system for applications. A thread monitors several pending operations in the thread pool. When a wait operation is completed, a secondary thread in the thread pool executes the corresponding callback function.

• To execute short tasks that require multiple threads, The threadpool class is the most convenient and best method to use multiple threads. Using a thread pool allows the system to optimize this situation not only for this process but also for other processes on the computer (your application knows nothing about it) to achieve better throughput. The thread pool enables the system to optimize the thread time slice after considering all the current processes on the computer.

Threadpool

• The thread pool is created when a threadpool class instance is created for the first time. The thread pool has the default limit of 25 threads per processor.

• Jobs unrelated to waiting operations can be arranged in the thread pool. To request a thread in the thread pool to process work items, call the queueuserworkitem method. This method is used as a parameter for reference to the method or delegate called by the selected thread from the thread pool. Once a work item is added to the queue, it cannot be canceled.

Create and terminate threads

Using system; using system. Threading; public class worker {// this method is called when the thread is started. Public void dowork () {While (! _ Shouldstop) {console. writeline ("worker thread: working... ");} console. writeline ("worker thread: Terminating gracefully. ");} public void requeststop () {_ shouldstop = true;} // volatile is used to prompt the compiler that this data // member will be accessed by multiple threads. Private volatile bool _ shouldstop;} public class workerthreadexample {static void main () {// create a thread object. This will not start the thread. Worker workerobject = new worker (); thread workerthread = new thread (workerobject. dowork); // start the auxiliary thread. Workerthread. Start (); console. writeline ("main thread: starting worker thread..."); // loops until the auxiliary thread is activated. While (! Workerthread. isalive); // sets the sleep time of 1 ms for the main thread, // to enable the auxiliary thread to complete a job. Thread. Sleep (1); // request the auxiliary thread to stop by itself: workerobject. requeststop (); // use the join method to block the current thread until the thread of the object stops. Workerthread. Join (); console. writeline ("main thread: worker thread has terminated .");}}

Use thread pool

The using system; using system. Threading; // Fibonacci class provides an interface for the use of the auxiliary // thread to perform the long-running Fibonacci (n) computation. // N is provided for the Fibonacci constructor. In addition, it also provides the event signal sent by the object when the // operation is complete. // Then, you can use the fibofn attribute to retrieve the result. Public class Fibonacci {public Fibonacci (int n, manualresetevent doneevent) {_ n = N; _ doneevent = doneevent;} // The packaging method used by the thread pool. Public void threadpoolcallback (Object threadcontext) {int threadindex = (INT) threadcontext; console. writeline ("thread {0} started... ", threadindex); _ fibofn = calculate (_ n); console. writeline ("thread {0} result calculated... ", threadindex); _ doneevent. set () ;}// Recursive Method for Calculating the nth Fibonacci number. Public int calculate (int n) {If (n <= 1) {return N;} else {return calculate (n-1) + calculate (n-2 );}} public int n {get {return _ n;} private int _ n; Public int fibofn {get {return _ fibofn ;}} private int _ fibofn; manualresetevent _ doneevent ;} public class threadpoolexample {static void main () {const int maid = 10; // each Fibonacci object uses an event manualresetevent [] doneevents = new manualresetevent [fibonaccicalculations]; maid [] maid = new maid (); random r = new random (); // use threadpool to configure and start the thread: console. writeline ("Launching {0} tasks... ", maid); For (INT I = 0; I <maid; I ++) {doneevents [I] = new manualresetevent (false); maid F = new maid (R. next (20, 40), doneevents [I]); fiber array [I] = f; threadpool. queueuserworkitem (F. threadpoolcallback, I);} // wait for all threads in the pool to execute computation... waithandle. waitall (doneevents); console. writeline ("Calculations complete. "); // display the result... for (INT I = 0; I <maid; I ++) {maid F = maid [I]; console. writeline ("Maid ({0}) = {1}", F. n, F. fibofn );}}}

Thread Synchronization and intercommunication

Using system; using system. threading; using system. collections; using system. collections. generic; // encapsulate thread synchronization events in this class, // so that these events can be passed to the consumer and // producer classes. Public class syncevents {public syncevents () {// autoresetevent is used for the "new project" event, because // we want the event to be automatically reset whenever the user thread responds to this event. _ Newitemevent = new autoresetevent (false); // manualresetevent is used for the "exit" event, because // We want multiple threads to respond when sending the event signal. // If autoresetevent is used, the event // object will be restored to the status of the unsent signal after a single thread responds, and other threads will be // unable to terminate. _ Exitthreadevent = new manualresetevent (false); // these two events are also placed in a waithandle array so that the // user thread can use the waitany method to block these two events. _ Eventarray = new waithandle [2]; _ eventarray [0] = _ newitemevent; _ eventarray [1] = _ exitthreadevent;} // The Public attribute allows secure access to events. Public eventwaithandle exitthreadevent {get {return _ exitthreadevent;} public eventwaithandle newitemevent {get {return _ newitemevent;} public waithandle [] eventarray {get {return _ eventarray ;}} private eventwaithandle _ newitemevent; private eventwaithandle _ exitthreadevent; private waithandle [] _ eventarray;} // The producer class (using a helper thread) // asynchronously adds an item to the queue, A total of 20 items are added. Public class producer {public producer (queue <int> q, syncevents e) {_ queue = Q; _ syncevents = E;} public void threadrun () {int COUNT = 0; random r = new random (); While (! _ Syncevents. exitthreadevent. waitone (0, false) {lock (icollection) _ Queue ). syncroot) {While (_ queue. count <20) {_ queue. enqueue (R. next (0,100); _ syncevents. newitemevent. set (); count ++ ;}} console. writeline ("producer thread: produced {0} items", count);} private queue <int> _ queue; private syncevents _ syncevents ;} // The consumer class uses the items in the queue through its own auxiliary thread. The producer class uses newitemevent // to notify the consumer class of the new item. Public class Consumer {public consumer (queue <int> q, syncevents e) {_ queue = Q; _ syncevents = E;} public void threadrun () {int COUNT = 0; while (waithandle. waitany (_ syncevents. eventarray )! = 1) {lock (icollection) _ Queue ). syncroot) {int item = _ queue. dequeue ();} count ++;} console. writeline ("Consumer thread: consumed {0} items", count);} private queue <int> _ queue; private syncevents _ syncevents ;} public class threadsyncsample {Private Static void showqueuecontents (queue <int> q) {// It is not thread-safe to enumerate collections, // Therefore, it is absolutely necessary to lock the set throughout the enumeration process to prevent the user and producer thread from modifying the content. (This method is only called by the // main thread .) Lock (icollection) q ). syncroot) {foreach (int I in Q) {console. write ("{0}", I) ;}} console. writeline ();} static void main () {// configuration structure, which contains the event information required for thread synchronization. Syncevents = new syncevents (); // a generic queue set is used to store the/items to be manufactured and used. In this example, "int" is used ". Queue <int> queue = new queue <int> (); // creates an object, one for manufacturing and one. The queue and thread synchronization events are passed to the two objects. Console. writeline ("logging ing worker threads... "); producer = new producer (queue, syncevents); consumer = new consumer (queue, syncevents); // creates a thread for the producer object and user object // object. This step does not create or start the // actual thread. Thread producerthread = new thread (producer. threadrun); thread consumerthread = new thread (consumer. threadrun); // create and start two threads. Console. writeline ("Launching producer and consumer threads... "); producerthread. start (); consumerthread. start (); // set a 10-second running time for the producer thread and user thread. // Use the main thread (the thread that executes this method) // display the queue content every 2.5 seconds. For (INT I = 0; I <4; I ++) {thread. sleep (2500); showqueuecontents (Queue);} // sends a termination signal to the user thread and producer thread. // Both threads will respond. Because exitthreadevent is a // manually reset event, it will be "set" unless explicitly reset ". Console. writeline ("signaling threads to terminate... "); syncevents. exitthreadevent. set (); // use join to block the main thread. First, it is blocked to the producer thread. // It is terminated, and then the user thread is terminated. Console. writeline ("main thread waiting for threads to finish..."); producerthread. Join (); consumerthread. Join ();}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.