我有一些线程(例如,线程1,线程2,线程3)和整数队列(例如1,2,3)。 每一秒,我想暂停当前正在运行的线程,并从队列中弹出,并运行具有相同ID的线程。
例如:
假设我有一个线程数组,以及一个保存当前正在执行的线程的整数。
int[] myThread; //1, 2, 3
ManualResetEventSlim[] mre;
executing = 1;
Queue myQueue; //2, 3
Time 0:01 //Thread 1 is running
Time 0:02 mre[executing].Wait();
myQueue.Enqueue(executing);
int nextThread = myQueue.Dequeue(); //say 2
mre[nextThread].Set();
executing = nextThread;
Time 0:03 //Same thing as at 0:02...
Time 0:04 //Same above
Time 0:05 //Same above
并希望输出看起来像这样:
Time 0:01 I'm 1
I'm 1
I'm 1
Time 0:02 I'm 2 // thread 2 was selected
I'm 2
I'm 2
Time 0:03 I'm 3 // thread 3 was selected
I'm 3
I'm 3
Time 0:04 I'm 2 // thread 2 was selected
I'm 2
I'm 2
我有一个定义操作的主文件:
static void Main()
{
CreateThread(Action, n);
}
public static void Action(int pid)
{
for(int i=0; i<100000; i++)
{
Trace.WriteLine("I'm "+ pid);
}
}
问题是一旦使用Set()设置了一个线程,就不能再使用Wait()来阻止它。因此,每个线程都会一直执行整个Action
方法,直到完成为止。
和输出看起来像这样:
Time 0:01 I'm 1 //Only Thread 1 is unblocked
I'm 1
I'm 1
Time 0:02 I'm 2 //Thread 2 was unblocked.
I'm 1 //Thread 1 is not blocked, so it keeps printing
I'm 2
Time 0:03 I'm 3 //Thread 3 was unblocked.
I'm 1 //Thread 1 is not blocked
I'm 2 //Thread 2 is not blocked either
我一直在研究这个问题并且卡住了。我真的很感激任何帮助。
答案 0 :(得分:0)
我不确定我是否理解这个问题,但我会更改Action()
,以便它需要ThreadData
的实例。你需要它来检查是否设置了MRE。如果是这样,请跳出迭代,让框架在线程之后进行清理。
public static void Action(ThreadData threadData)
{
for (int i = 0; i < 100000; i++)
{
if (threadData.Mre.IsSet)
{
break;
}
Trace.WriteLine("I'm " + threadData.Pid);
}
}
修改强>
您可能没有意识到,但您可能正在为每个线程使用相同的MRE实例。每个线程都引用mre
变量。在将mre
设置为新实例之前,谁会说该线程已启动?剧透:它没有。