线程之间同步
来源:互联网 发布:月入10万的网络女主播 编辑:程序博客网 时间:2024/06/05 20:37
线程之间同步(主要结合前人的文章,加上自己的理解,整理而成,希望对你有用..)
//想明白了就好了.....
1 Mutex的WaitOne()函数
{
static void Main(string[] args)
{
// 为截图方便把窗体设小一点
Console.WindowWidth = 30; Console.BufferWidth = 30;
Console.WindowHeight = 16; Console.BufferHeight = 16;
Mutex mk = new Mutex(false, "my mutex");
for (int i = 0; i < 1000; i++)
{
mk.WaitOne();
for (int j = 0; j < 30; j++)
{
Console.Write(">");
Thread.Sleep(100);
}
mk.ReleaseMutex();
Thread.Sleep(500);
}
}
}
接连运行此程序的两个实例,把它们并排排放在一起(如下图所示),即可看到箭头从左边的窗体“穿越”到右边窗体的效果了。Mutex和Monitor的概念十分相似,只不过Monitor是.net内建的线程同步机制,Mutex是封装了Windows操作系统的线程同步机制;Monitor速度快,Mutex的速度要比Monitor慢很多;Monitor只能用于同步同一进程内的线程;Mutex则可以用于同步隶属于不同进程的线程。
2:
Mutex的WaitAll()函数
{
static void Main(string[] args)
{
// 为截图方便把窗体设小一点
Console.WindowWidth = 30; Console.BufferWidth = 30;
Console.WindowHeight = 16; Console.BufferHeight = 16;
Mutex mk1 = new Mutex(false, "my mutex1");
Mutex mk2 = new Mutex(false, "my mutex2");
Mutex[] mks = new Mutex[] { mk1, mk2 };
for (int i = 0; i < 1000; i++)
{
Mutex.WaitAll(mks);
for (int j = 0; j < 30; j++)
{
Console.Write(">");
Thread.Sleep(100);
}
mk1.ReleaseMutex();
mk2.ReleaseMutex();
Thread.Sleep(500);
}
}
}
3:
Mutex的WaitAny()函数:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 // 为截图方便把窗体设小一点
6 Console.WindowWidth = 30; Console.BufferWidth = 30;
7 Console.WindowHeight = 16; Console.BufferHeight = 16;
8
9 Mutex mk1 = new Mutex(false, "my mutex1");
10 Mutex mk2 = new Mutex(false, "my mutex2");
11 Mutex[] mks = new Mutex[] { mk1, mk2 };
12
13 for (int i = 0; i < 1000; i++)
14 {
15 int index = Mutex.WaitAny(mks); // 返回值为此进程占用的mk在mks里的index
16 Console.Write("Index: " + index.ToString());
17 for (int j = 0; j < 30; j++)
18 {
19 Console.Write(">");
20 Thread.Sleep(100);
21 }
22
23 mks[index].ReleaseMutex();
24 Thread.Sleep(new Random().Next(100, 3000));
25 }
26 }
27 }
如果同时运行此程序的两个实例,正如本文摘要里所写的,只要mk1和mk2有一个是空闲的,进程就可以进去办事,所以两个进程可以同时输出">"字符。注意程序的第24行,每个进程在输出30个">"字符后都会随机Sleep 100到3000毫秒,这样就有可能出现mk1和mk2同时空闲的情况,所以就会出现一会儿进程1占用mk1而进程2占用mk2;一会儿进程1占用mk2而进程2占用mk1的情况(在下图分别用绿色和红色波浪线标出)。
4:
using System;
using System.Threading;
public class Example
{
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
private static EventWaitHandle ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
private static long threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
private static EventWaitHandle clearCount =
new EventWaitHandle(false, EventResetMode.AutoReset);
[MTAThread]
public static void Main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for (int i = 0; i <= 4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while (Interlocked.Read(ref threadCount) > 0)
{
Console.WriteLine("Press ENTER to release a waiting thread.");
Console.ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle.SignalAndWait(ewh, clearCount);
}
Console.WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
// Create and start five more numbered threads.
//
for(int i=0; i<=4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console.WriteLine("Press ENTER to release the waiting threads.");
Console.ReadLine();
ewh.Set();
}
public static void ThreadProc(object data)
{
int index = (int) data;
Console.WriteLine("Thread {0} blocks.", data);
// Increment the count of blocked threads.
Interlocked.Increment(ref threadCount);
// Wait on the EventWaitHandle.
ewh.WaitOne();
Console.WriteLine("Thread {0} exits.", data);
// Decrement the count of blocked threads.
Interlocked.Decrement(ref threadCount);
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount.Set();
}
}
- 线程之间同步
- 线程之间的同步
- 线程之间同步问题
- 线程之间的同步
- [线程]--线程之间的同步
- Windows Mobile 线程之间同步
- 线程之间的同步通信
- 线程之间和进程之间的同步
- 【线程间同步】Android线程之间如何进行同步
- 使用condition variable实现线程之间同步
- 学习日记java 线程之间的同步
- 线程之间的互斥和同步
- 线程之间的互斥和同步
- 线程之间的同步和互斥
- 线程面试题之二:子线程之间的同步
- 线程同步3 ------ 信号量实现进程或者线程之间的同步
- VC中利用多线程技术实现线程之间的通信(三)---线程之间的同步
- 多线程的使用方式和线程之间同步种类
- 移动设备阅读体验
- Android 4.0新增WiFiDirect功能
- 多表连接修改语句
- 免费ARP简介
- VB.NET使文本框只能输入数字
- 线程之间同步
- 2063 照亮的面积
- 将HTML5封装成android应用APK 文件若干方法
- java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlException
- 保护您的 ASP.NET 应用程序
- 相频响应与群延迟
- reactos 编译,安装篇
- 2074 修改病句
- C#编程中的66个好习惯