积极答复者
关于c#锁阻塞的问题

问题
-
你好,我要写个程序100ms内处理第三方dll返回的10000条数据,如果处理不完第三方dll就会抛出错误导致程序关闭。
于是我分两个线程写,一个线程读取数据到queue,保证100ms中能够读光10000条数据,另外线程每隔一段时间处理这些数据并把结果保存到数据库。
用queue时多线程需要加lock,否则会报错index out of range(网上查了,貌似ms的bug),但是加了锁之后却发现又不能再100ms内处理完这10000条数据了,于是第三方dll又报错,不知道我这种情况应该怎么处理比较好,麻烦的是100ms中必须把10000个数据加入到队列以便另外的线程处理,同时又不能加锁,如果加锁貌似就没有多线程的效果了。谢谢!
答案
-
是的,用lock的话恐怕无法达到此目的。你可以使用消息锁来完成此目的(另外不要开辟另外一个线程保存,直接子线程完成某个任务,直接保存)。
此示例演示如何使用分段求和方式求出1~10000的和:
public class Test { public static void Main() { int[] numbers = new int[10000]; //分段求和结果存放 int[] sums = new int[5]; const int BLOCK = 2000; //每个线程统计2000个数字和 for (int i = 1; i <=10000; i++) { numbers[i - 1] = i; } AutoResetEvent[] flags = new AutoResetEvent[5]; for (int i = 0; i < 5; i++) { int temp = i; flags[temp] = new AutoResetEvent(false); //初始化信号为空 } //线程池,开辟5个线程 for (int i = 0; i <5; ++i) { int temp = i; Thread th = new Thread(new ThreadStart( delegate() { for (int j = temp * BLOCK; j < temp * BLOCK + BLOCK; ++j) { sums[temp] += numbers[j]; } //此处直接写入数据库,因为当前线程已经完成任务了 Console.WriteLine("线程"+(i+1)+"已经完成任务,分布求和为:"+sums[i]); flags[temp].Set(); })); th.IsBackground = true; th.Start(); } WaitHandle.WaitAll(flags); Console.WriteLine(sums.Sum()); } }
【执行结果】
- 已建议为答案 Mike FengModerator 2012年6月20日 10:36
- 已标记为答案 Mike FengModerator 2012年7月8日 8:55
全部回复
-
是的,用lock的话恐怕无法达到此目的。你可以使用消息锁来完成此目的(另外不要开辟另外一个线程保存,直接子线程完成某个任务,直接保存)。
此示例演示如何使用分段求和方式求出1~10000的和:
public class Test { public static void Main() { int[] numbers = new int[10000]; //分段求和结果存放 int[] sums = new int[5]; const int BLOCK = 2000; //每个线程统计2000个数字和 for (int i = 1; i <=10000; i++) { numbers[i - 1] = i; } AutoResetEvent[] flags = new AutoResetEvent[5]; for (int i = 0; i < 5; i++) { int temp = i; flags[temp] = new AutoResetEvent(false); //初始化信号为空 } //线程池,开辟5个线程 for (int i = 0; i <5; ++i) { int temp = i; Thread th = new Thread(new ThreadStart( delegate() { for (int j = temp * BLOCK; j < temp * BLOCK + BLOCK; ++j) { sums[temp] += numbers[j]; } //此处直接写入数据库,因为当前线程已经完成任务了 Console.WriteLine("线程"+(i+1)+"已经完成任务,分布求和为:"+sums[i]); flags[temp].Set(); })); th.IsBackground = true; th.Start(); } WaitHandle.WaitAll(flags); Console.WriteLine(sums.Sum()); } }
【执行结果】
- 已建议为答案 Mike FengModerator 2012年6月20日 10:36
- 已标记为答案 Mike FengModerator 2012年7月8日 8:55