I. manualresetevent
This object has two semaphore states: true and false. The constructor sets the initial state.
- Waitone: This method is used to block threads. By default, the thread is blocked for an indefinite period of time. Timeout blocking is supported. If the thread times out, blocking is abandoned, which avoids waiting for an indefinite period of time;
- Set: manually change the semaphore to true, that is, resume thread execution;
- Reset: reset status;
Class program {public static void main () {thread t = new thread (run); T. name = "Auxiliary thread"; T. start (); console. writeline ("Current Time: {0} {1} Ready for execution! ", Datetime. Now. timeofday, T. Name); // manually change the semaphore to true, that is, to restore a waiting thread for execution. Mr. set (); console. readkey ();} // when it is set to false at the beginning, the static manualresetevent mr = new manualresetevent (true) is executed only after the signal is received. Static void run () {// The thread is on standby when execution starts, and the Mr is started only after receiving the signal. waitone (); console. writeline ("\ n current time: {0} {1} officially executed! ", Datetime. now. timeofday, thread. currentthread. name); // I want to pause the auxiliary thread for 3 seconds. waitone (3000); console. writeline ("\ n current time: {0} {1} paused for 3 seconds, but invalid! ", Datetime. now. timeofday, thread. currentthread. name); // I want the auxiliary thread to pause mr. reset (); console. writeline ("\ n current time: {0} {1} is still invalid! ", Datetime. Now. timeofday, thread. currentthread. Name );}}
The output is as follows:
Reset () actually means resetting, and then waitone ();
Class program {public static void main () {thread t = new thread (run); T. name = "Auxiliary thread"; T. start (); console. writeline ("Current Time: {0} {1} Ready for execution! ", Datetime. Now. timeofday, T. Name); // manually change the semaphore to true, that is, to restore a waiting thread for execution. Mr. set (); thread. sleep (1, 10000); Mr. set (); console. readkey ();} // when it is set to false at the beginning, the static manualresetevent mr = new manualresetevent (false) is executed only after the signal is received. Static void run () {// The thread is on standby when execution starts, and the Mr is started only after receiving the signal. waitone (); console. writeline ("\ n current time: {0} {1} officially executed! ", Datetime. now. timeofday, thread. currentthread. name); // The Mr is valid only when it is stopped After resetting. reset (); // I want to pause the auxiliary thread for 3 seconds. waitone (3000); console. writeline ("\ n current time: {0} {1} paused for 3 seconds, this time valid! ", Datetime. now. timeofday, thread. currentthread. name); // The Mr is valid only when it is stopped After resetting. reset (); // I want to pause the auxiliary thread. After 10, the main thread will wake up Mr again. waitone (); console. writeline ("\ n current time: {0} {1} paused, but will be awakened by the main thread again, this time is valid! ", Datetime. Now. timeofday, thread. currentthread. Name );}}
The output is as follows:
Ii. autoresetevent
The difference between autoresetevent and manualresetevent is that the waitone of autoresetevent changes the semaphore value.
For example, if the initial semaphore is true, the waitone timeout semaphore will automatically become false, but manualresetevent will not.
Class program {public static void main () {thread t = new thread (run); T. name = "Auxiliary thread"; T. start (); console. writeline ("Current Time: {0} {1} Ready for execution! ", Datetime. now. timeofday, T. name); console. readkey ();} static autoresetevent AR = new autoresetevent (true); static void run () {var state = ar. waitone (1000); console. writeline ("Current semaphore status: {0}", State); State = ar. waitone (1000); console. writeline ("after waitone again, the current status is: {0}", state );}}
The output is as follows:
If you want to achieve the same effect as manualresetevent, you do not need to manually reset () The run method:
Static void run () {// standby when the thread starts execution. The Mr is started only after receiving the signal. waitone (); console. writeline ("\ n current time: {0} {1} officially executed! ", Datetime. now. timeofday, thread. currentthread. name); // I want to pause the auxiliary thread for 3 seconds. waitone (3000); console. writeline ("\ n current time: {0} {1} paused for 3 seconds, this time valid! ", Datetime. now. timeofday, thread. currentthread. name); // I want to pause the auxiliary thread. After 10, the main thread will wake up Mr again. waitone (); console. writeline ("\ n current time: {0} {1} paused, but will be awakened by the main thread again, this time is valid! ", Datetime. Now. timeofday, thread. currentthread. Name );}
The manual reset () code is missing.
Iii. semaphore
Used to control the number of threads to access. The default constructor is initialcount and maximumcount, indicating the number of semaphores and the maximum number of semaphores set by default. When you waitone, The semaphores are automatically reduced. When the release is used, the semaphores are automatically increased. However, when the semaphores are 0, the subsequent threads cannot get the waitone, therefore, you must wait for the previous thread to release it through release.
Class program {static void main (string [] ARGs) {thread T1 = new thread (run1); t1.start (); thread t2 = new thread (run2); t2.start (); thread T3 = new thread (run3); t3.start (); console. read () ;}// initially two threads can be granted, because the first 3rd threads need to wait for the previous release to obtain the signal static semaphore SEM = new semaphore (2, 10 ); static void run1 () {SEM. waitone (); console. writeline ("Hello everyone, I'm run1" + datetime. now. timeofday);} static void run2 () {SEM. waitone (); console. writeline ("Hello everyone, I am run2" + datetime. now. timeofday); // thread after two seconds. sleep (2000); SEM. release ();} static void run3 () {SEM. waitone (); console. writeline ("Hello everyone, I am run3" + datetime. now. timeofday );}}
Output:
In the above method, the release () method is equivalent to auto-incrementing a semaphore, and release (5) Auto-incrementing 5 semaphores. However, the value from release () to the second maximumcount parameter of the constructor cannot be auto-incrementing.
The named semaphore can be used for process-level interaction.
Class program {static void main (string [] ARGs) {thread T1 = new thread (run1); t1.start (); thread t2 = new thread (run2); t2.start (); console. read ();} // initially two threads can be granted, because the first 3rd threads need to wait for the previous release to obtain the signal static semaphore SEM = new semaphore (3, 10, "Name semaphore"); static void run1 () {SEM. waitone (); console. writeline ("process:" + process. getcurrentprocess (). ID + "I am run1" + datetime. now. timeofday);} static void run2 () {SEM. waitone (); console. writeline ("process:" + process. getcurrentprocess (). ID + "I am run2" + datetime. now. timeofday );}}
The output is as follows:
- Manualresetevent: one or more threads can be awakened each time;
- Autoresetevent:Only one thread can be awakened at a time;
Semaphores <Article 6>