最近,我收到了一封电子邮件,要求我帮忙解决一些问题。 The mail was not a good question(它没有任何代码,只有一个堆栈跟踪...),但经过一些思考和搜索,我可以假设它是因为同步问题。他可能没有锁定queue.Enqueue();
,所以我写了#34;你应该做lock
!"作为回应。
然后,我觉得向他展示一个小例子很好。
using System;
using System.Collections.Generic;
using System.Threading;
static class Program
{
private static Queue<int> q = new Queue<int>();
static void Main(string[] args)
{
Thread[] thrds = new Thread[100];
for (int i = 0; i < 100; i++)
{
//thrds[i] = new Thread(do_safe);
thrds[i] = new Thread(do_unsafe); // <--
thrds[i].Start(i);
}
for (int i = 0; i < 100; i++)
{
thrds[i].Join();
}
foreach (int i in q)
{
Console.WriteLine(i);
}
}
private static void do_safe(object k)
{
int val = (int)k;
for (int i = 0; i < 100; i++) // do something
{
val += i;
Thread.Sleep(0);
}
lock (q)
q.Enqueue(val); // with locking
}
private static void do_unsafe(object k)
{
int val = (int)k;
for (int i = 0; i < 100; i++) // do something
{
val += i;
Thread.Sleep(1);
}
q.Enqueue(val); // without locking
}
}
我在ideone上对其进行了测试,正如我所料,该程序与do_unsafe
崩溃并与do_safe
配合使用。
然而,我发现崩溃信息很快就会变得很奇怪。
ves_icall_System_Threading_Thread_Thread_internal: CreateThread error 0x0
Unhandled Exception: System.SystemException: Thread creation failed.
at System.Threading.Thread.Start () [0x00000] in <filename unknown>:0
at System.Threading.Thread.Start (System.Object parameter) [0x00000] in <filename unknown>:0
at Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.SystemException: Thread creation failed.
at System.Threading.Thread.Start () [0x00000] in <filename unknown>:0
at System.Threading.Thread.Start (System.Object parameter) [0x00000] in <filename unknown>:0
at Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
由于q.Enqueue
发生同步问题,我预计会在其中抛出一些异常。 (实际上,邮件就是这样说的。)
但是崩溃消息说线程创建失败了。我知道线程同步问题会导致任何错误问题,(这种情况可能是一个很好的做法&gt; o&lt;)但我无法理解为什么线程创建与此同步问题相关联。
你能给我一个详细的解释吗?