线程和任务调度
本文关键字:任务调度 线程 | 更新日期: 2023-09-27 18:28:40
我有一个通过AutoResetEvent
同步线程的代码
基本上有两个线程交换控制和执行命令,每个线程一次执行。
代码:
static EventWaitHandle _waitHandle = new AutoResetEvent(false);
static void Waiter()
{
_waitHandle.WaitOne();
Console.WriteLine("A...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("A2...");
_waitHandle.Set();
}
static void Waiter2()
{
_waitHandle.WaitOne();
Console.WriteLine("B...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("B2...");
}
void Main()
{
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
_waitHandle.Set(); // Wake up the Waiter.
}
结果:(我总是得到这个结果)
A...
B...
A2...
B2...
然而,当我转到Tasks
:时
Task.Run(()=>Waiter());
Task.Run(()=>Waiter2());
我有时会得到:
B...
A...
B2...
这一点我很清楚,因为任务调度程序将第二个任务安排为首先执行。
这让我不禁要问:
问题
1) 线程顺序是否保证与中的调用顺序相同
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
//In other words , will I always get the first result ?
2) 如何强制以与调用Task.Run
相同的顺序调用它们?
- 不,这并不能保证,你只是很幸运,每次的输出都是一样的
- 在两个任务之间添加具有
WaitOne
的第二个AutoResetEvent
,并在Waiter
方法开始时添加Set
如果没有同步机制,就无法保证线程启动和/或执行的顺序。此外,线程的执行可能在任何时候被抢占(想想:"暂停")。
因此,为了回答您的问题:
- 否
- 否
在前进之前,你应该问问自己"我真的需要使用线程来解决这个问题吗?"
我最喜欢微软MSDN上的一句话:
"当你使用任何类型的多线程时,你都可能会暴露出非常严重和复杂的错误"[
如果您确实需要介绍线程,那么我将首先熟悉微软的一些同步机制:
- 关键部分
- Mutex
- 事件
- 自动复位
- 手动复位