我有几个线程使用类似于下面代码的东西从队列中消耗任务。问题是有一种类型的任务在处理任何其他任务时无法运行。
这就是我所拥有的:
while (true) // Threaded code
{
while (true)
{
lock(locker)
{
if (close_thread)
return;
task = GetNextTask(); // Get the next task from the queue
}
if (task != null)
break;
wh.WaitOne(); // Wait until a task is added to the queue
}
task.Run();
}
这就是我需要的东西:
while (true)
{
while (true)
{
lock(locker)
{
if (close_thread)
return;
if (disable_new_tasks)
{
task = null;
}
else
{
task = GetNextTask();
}
}
if (task != null)
break;
wh.WaitOne();
}
if(!task.IsThreadSafe())
{
// I would set this to false inside task.Run() at
// the end of the non-thread safe task
disable_new_tasks = true;
Wait_for_all_threads_to_finish_their_current_tasks();
}
task.Run();
}
问题是我不知道如何在不造成混乱的情况下实现这一目标。
答案 0 :(得分:1)
尝试使用TreadPool,然后使用WaitHandle.WaitAll方法确定所有线程都已完成执行。
答案 1 :(得分:0)
WaitHandle.WaitAll(autoEvents); 也许这就是你想要的。
class Calculate
{
double baseNumber, firstTerm, secondTerm, thirdTerm;
AutoResetEvent[] autoEvents;
ManualResetEvent manualEvent;
// Generate random numbers to simulate the actual calculations.
Random randomGenerator;
public Calculate()
{
autoEvents = new AutoResetEvent[]
{
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false)
};
manualEvent = new ManualResetEvent(false);
}
void CalculateBase(object stateInfo)
{
baseNumber = randomGenerator.NextDouble();
// Signal that baseNumber is ready.
manualEvent.Set();
}
// The following CalculateX methods all perform the same
// series of steps as commented in CalculateFirstTerm.
void CalculateFirstTerm(object stateInfo)
{
// Perform a precalculation.
double preCalc = randomGenerator.NextDouble();
// Wait for baseNumber to be calculated.
manualEvent.WaitOne();
// Calculate the first term from preCalc and baseNumber.
firstTerm = preCalc * baseNumber *
randomGenerator.NextDouble();
// Signal that the calculation is finished.
autoEvents[0].Set();
}
void CalculateSecondTerm(object stateInfo)
{
double preCalc = randomGenerator.NextDouble();
manualEvent.WaitOne();
secondTerm = preCalc * baseNumber *
randomGenerator.NextDouble();
autoEvents[1].Set();
}
void CalculateThirdTerm(object stateInfo)
{
double preCalc = randomGenerator.NextDouble();
manualEvent.WaitOne();
thirdTerm = preCalc * baseNumber *
randomGenerator.NextDouble();
autoEvents[2].Set();
}
public double Result(int seed)
{
randomGenerator = new Random(seed);
// Simultaneously calculate the terms.
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateBase));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateFirstTerm));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateSecondTerm));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateThirdTerm));
// Wait for all of the terms to be calculated.
**WaitHandle.WaitAll(autoEvents);**
// Reset the wait handle for the next calculation.
manualEvent.Reset();
return firstTerm + secondTerm + thirdTerm;
}
}
答案 2 :(得分:0)
您可以将此视为类似于允许任意数量的读者或一个作者的数据结构。也就是说,任意数量的线程都可以读取数据结构,但写入数据结构的线程需要独占访问。
在您的情况下,您可以运行任意数量的“常规”线程,或者您可以拥有一个需要独占访问权限的线程。
.NET具有ReaderWriterLock
和ReaderWriterLockSlim
类,您可以使用它们来实现这种共享。不幸的是,xbox上都没有这些类。
但是,可以从Monitor
和ManualResetEvent
对象的组合实现读取器/写入器锁定。我没有C#示例(为什么我会,因为我可以访问本机对象?),但是有一个simple Win32 implementation不应该非常难以移植。
答案 3 :(得分:-1)
你可以使用这样的东西,
ExecutorService workers = Executors.newFixedThreadPool(10);
for(int i=0; i<input.length; i++) {
Teste task = new Teste(rowArray,max);//your thread class
workers.execute(task);
}
workers.shutdown();//ask for shut down
while(!workers.isTerminated()) {//wait until all finishes.
try {
Thread.sleep(100);//
} catch (InterruptedException exception) {
}
System.out.println("waiting for submitted task to finish operation");
}
希望得到这个帮助。