我正在尝试使用可重用的工作线程构建某种多线程游戏引擎。这意味着工作程序正在运行无限循环,并且在每次迭代之后,调用一个方法,该方法使用class WorkerThread
{
private readonly Game game;
private readonly Task task;
private readonly AutoResetEvent waitEvent;
private readonly AutoResetEvent finishEvent;
public string Message { get; set; }
public bool Active { get; private set; }
public WorkerThread(Game game)
{
this.game = game;
waitEvent = new AutoResetEvent(false);
finishEvent = new AutoResetEvent(false);
task = new Task(startTask);
}
public void Start()
{
task.Start();
}
public void PerformFrame()
{
finishEvent.Reset();
waitEvent.Set();
}
public void WaitForFrameToFinish()
{
finishEvent.WaitOne();
}
private void startTask()
{
WaitFrame();
run();
}
long sum;
private void run()
{
while (true)
{
sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum += i;
}
Console.WriteLine(Message);
WaitFrame();
}
}
private void WaitFrame()
{
Active = false;
finishEvent.Set();
waitEvent.WaitOne();
Active = true;
}
}
class Game
{
private readonly List<WorkerThread> workers = new List<WorkerThread>();
public Game()
{
workers.Add(new WorkerThread(this) { Message = "Worker 1" });
workers.Add(new WorkerThread(this) { Message = "Worker 2" });
workers.Add(new WorkerThread(this) { Message = "Worker 3" });
workers.Add(new WorkerThread(this) { Message = "Worker 4" });
workers.Add(new WorkerThread(this) { Message = "Worker 5" });
workers.Add(new WorkerThread(this) { Message = "Worker 6" });
}
public void Start()
{
foreach (WorkerThread worker in workers)
{
worker.Start();
}
}
public void OneFrame()
{
//start every worker
foreach (WorkerThread worker in workers)
{
worker.PerformFrame();
}
//wait for the workers to finish
foreach (WorkerThread worker in workers)
{
worker.WaitForFrameToFinish();
}
//check if there are workers still running
foreach (WorkerThread worker in workers)
{
if (worker.Active)
{
Console.WriteLine(worker.Message + " still active");
}
}
Console.WriteLine("Frame finished.\n");
}
}
挂起线程,直到从外部开始下一次迭代。这很好用。
但后来我想等待所有工作线程进入等待状态。但是在第一步中总是忽略最后一个线程。
这是我的代码:
Game
有谁知道为什么WorkerThread
等待最后ManualResetEventSlim
完成任务?
编辑:使用AutoResetEvent
代替n = write(sockfd, buf, sizeof(buf));
解决问题。但我仍然不明白为什么以上都不起作用。
编辑2:我找到了答案并将其发布在下面。
答案 0 :(得分:1)
我刚刚找到了解决方案。 startTask
使用设置WaitFrame
的{{1}}方法。那样finishEvent
将不会在第一次迭代时等待工作者,因为WaitForFrameToFinish
已经设置好了。
如果你这样做,它可以正常工作:
finishEvent