我估计应该是很简单的一个问题,请各位帮忙解惑!有一个list,需要把它的每个元素进行一下处理,但是在处理过程中可能生成新的元素又加到这个list里来,因此其大小是不固定的
现在我想采用并行计算来处理这个list,初步思路是:假设有两个核,我把这个list平均分成两部分作为两个task,然后调用parallel.invoke,但是这两个list中,每个list生成新的元素的数量是不一定的,也就是说,也许运行过程中,task2还有好多元素没有处理,但task1开始闲着了请问这种情况该怎么处理?我用的方式是最佳方式么?
现在我想采用并行计算来处理这个list,初步思路是:假设有两个核,我把这个list平均分成两部分作为两个task,然后调用parallel.invoke,但是这两个list中,每个list生成新的元素的数量是不一定的,也就是说,也许运行过程中,task2还有好多元素没有处理,但task1开始闲着了请问这种情况该怎么处理?我用的方式是最佳方式么?
解决方案 »
- DataGroupView控件技巧
- 安装windows服务指定为LocalSystem 还要输入账户名和密码
- winform如何同时导出4个datagridview到word
- C#如何实现文件保存对话框自动保存
- 问个按引用传值的
- Spread for web 刷新的问题???
- 求助高手,窗口重绘问题
- 在C#中如何快速向前移动数据库游标
- listview如何实现列选择功能
- 写文件到另一台服务器,出错?The remote server returned an error: (403) Forbidden.
- 同样的代码,使用SpeechSynthesizer报读,在win7报读的是中文,在xp变成了英文,怎么回事
- c# FTP 断点续传
两边线程同时
while(Queue.Count>0)
{
lock(Queue)
{
xxx=Queue.DeQueue();
}
}另外你就随边向Queue.EnQueue(Item)就行了。
标准做法。
那意思是,如果我有四个核,那么就重复四边
谢谢,请问用list为什么不行呢?我看这些功能用list都能实现啊
Queue好处是,某项执行完了,就出队,List不会,如果用List你要做好几个判断
最近在实现socket服务器的延时任务系统功能:即上层应用不断将需要过一段时间执行的功能委托给任务系统,任务系统再在其自己维护的线程中扫描待执行任务列表,如果到达执行时间,则执行此任务。经过几次实践发现,使用Monitor的Wait, Pulse 和PulseAll方法实现一种生产者/消费者模式,是个不错的解决方案。
Monitor的Wait, Pulse 和 PulseAll用于在多线程通信。如果一个线程调用了Wait,则该线程将阻塞,Monitor将被释放,直到有其他线程调用了Pulse 或者 PulseAll。Pulse只唤醒一个正在Wait的线程,而PulseAll则将唤醒所有等待Monitor的线程。
这些方法最常用于生产者/消费者的情形:一个线程把工作项放入队列,其他线程将工作项取出。消费线程通常一直取出工作项直到消耗光,然后等待锁,生产线程则在将工作项添加进队列后,调用Monitor的Pulse使得消费线程开始工作。
下面的代码演示了这些方法的简单用法:
using System;
using System.Collections;
using System.Threading; public class Test
{
static ProducerConsumer queue;
static void Main()
{
queue = newProducerConsumer();
new Thread(newThreadStart(ConsumerJob)).Start();
Random rng = new Random(0);
for(int i=0; i < 10; i++)
{
Console.WriteLine ("Producing {0}", i);
queue.Produce(i);
Thread.Sleep(rng.Next(1000));
}
} static void ConsumerJob()
{
// Make sure we get a different random seed from the
// first thread
Random rng = newRandom(1); // We happen to know we've only got 10
// items to receive
for(inti=0; i < 10; i++)
{
object o = queue.Consume();
Console.WriteLine ("\t\t\t\tConsuming {0}", o);
Thread.Sleep(rng.Next(1000));
}
}
}public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue(); public void Produce(objecto)
{
lock(listLock)
{
queue.Enqueue(o); // We always need to pulse, even if the queue wasn't
// empty before. Otherwise, if we add several items
// in quick succession, we may only pulse once, waking
// a single thread up, even if there are multiple threads
// waiting for items.
Monitor.Pulse(listLock);
}
} public object Consume()
{
lock(listLock)
{
// If the queue is empty, wait for an item to be added
// Note that this is a while loop, as we may be pulsed
// but not wake up before another thread has come in and
// consumed the newly added object. In that case, we'll
// have to wait for another pulse.
while(queue.Count==0)
{
// This releases listLock, only reacquiring it
// after being woken up by a call to Pulse
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}
运行上述代码后,将产生类似下面的输出:
Producing 0
Consuming 0
Producing 1
Consuming 1
Producing 2
Consuming 2
Producing 3
Consuming 3
Producing 4
Producing 5
Consuming 4
Producing 6
Consuming 5
Consuming 6
Producing 7
Consuming 7
Producing 8
Consuming 8
Producing 9
Consuming 9
我是意思,你在从List取出 取什么由你决定,取出后插到队列里。明白?
谢谢兄台。
我还有个问题,我使用.net 4.0中的TPL实现这个的,我的做法是定义了两个task,每个task都从一个公共的queue里取值,但遇到的问题是:刚开始queue里只有一个元素,第一个task取到这个元素后,就把它删了,但这时第一个task还在运行,还没有生成新的元素,第二个task也开始了,它看见queue是空的,就自动结束了
于是,程序永远都在第一个task里执行,又成了串行模式了
请问,该怎么避免这种情况呢?
不要用task,直接用Thread吧 你所但心的那是没必要的 while(queue.Count==0)
{
// This releases listLock, only reacquiring it
// after being woken up by a call to Pulse
Monitor.Wait(listLock); 《-这句是指如果queue为空了,就让线程等待,直到有新的数据装入到queue里面线程才会继续下去。 不用但心他会退出
}
{
lock(queue)....
if(Queue.Count==list.count)break;
}
if(计数器==list.count)break;
原来是这样多谢
那么请问,task最后要落到thread上来,是不是所有用task实现的,都能用thread实现?
用thread应该比用task更快吧?