多核時代 .NET Framework 4 中的並行程式設計5---並行迴圈Parallel Loop
1. 並行迴圈與順序迴圈區別
首先,來執行下面的程式碼,檢視區別,程式碼如下:
static void Main(string[] args)
{
Console.WriteLine("使用For迴圈");
for (int i = 0; i <= 10; i++)
{
Console.WriteLine("i = {0}, 執行緒id = {1}",
i, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
}
Console.WriteLine("使用Parallel.For");
Parallel.For(0, 10, i =>
{
Console.WriteLine("i = {0}, 執行緒id = {1}", i,
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
});
Console.ReadLine();
}
最終執行的效果如下圖所示:
從上面的程式碼執行效果圖來我們可以看到,只有一個執行緒在處理for迴圈.而Parallel.For的迴圈,則會有多個執行緒進行處理,從而在某種程度改善了程式程式碼的執行效率.他們的區別就不言而喻.
2. Parallel的並行迴圈的幾種方法
Parallel類提供以下幾種並行執行迴圈的方法(他們還有很多其他的過載方法)。具體說明如下:
Ø Parallel.For:執行 for 迴圈,其中可能會並行執行迭代.
Ø Parallel.ForEach: 對某種集合中的物件執行 foreach,其中可能會並行執行迭代,需要主要的是,它不保證按照集合的索引順序去執行迭代。
Ø Parallel.Invoke:儘可能並行執行提供的每個操作.
示例程式碼如下:
private static void Invoke()
{
Action[] actions = new Action[5];
actions[0] = new Action(() =>
{
Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);
});
actions[1] = new Action(() =>
{
Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);
});
actions[2] = new Action(() =>
{
Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);
});
actions[3] = new Action(() =>
{
Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);
});
actions[4] = new Action(() =>
{
Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);
});
Parallel.Invoke(actions);
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6 };
Parallel.ForEach(list, i =>
{
Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);
});
Console.ReadLine();
}
3. 返回值
ParallelLoopResult提供執行 Parallel 迴圈的完成狀態。其中, ParallelLoopResult有兩個屬性:
Ø IsCompleted 獲取該迴圈是否已執行完成(即,該迴圈的所有迭代均已執行,並且該迴圈沒有收到提前結束的請求)。
Ø LowestBreakIteration 獲取從中呼叫 Break 的最低迭代的索引。
程式碼如下:
ParallelLoopResult loopResult = Parallel.ForEach(list, (int i,ParallelLoopState state) =>
{
if (i == 5)
{
state.Break();
}
Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);
});
Console.WriteLine("IsCompleted: {0}", loopResult.IsCompleted);
Console.WriteLine("BreakValue: {0}", loopResult.LowestBreakIteration.HasValue);
Console.ReadLine();
4. 控制迴圈
ParallelOptions類儲存用於配置 Parallel 類的方法的操作的選項。其屬性有:
Ø CancellationToken 獲取或設定與此 ParallelOptions 例項關聯的 CancellationToken。
Ø MaxDegreeOfParallelism 獲取或設定此 ParallelOptions 例項所允許的最大並行度。
Ø TaskScheduler 獲取或設定與此 ParallelOptions 例項關聯的 TaskScheduler。 將此屬性設定為 null,以指示應使用當前計劃程式。
如下程式碼,通過設定CancellationToken以便可以取消Parallel的迴圈:
CancellationTokenSource token = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
token.Cancel();
Console.WriteLine("Token Cancelled.");
});
ParallelOptions loopOptions = new ParallelOptions()
{
CancellationToken = token.Token,
MaxDegreeOfParallelism = 2
};
try
{
Parallel.For(0, Int64.MaxValue, loopOptions, i =>
{
Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
});
}
catch (OperationCanceledException)
{
Console.WriteLine("Exception...");
}
其中, MaxDegreeOfParallelism設定為2,表示最多可以有2個並行量(可以理解成並行執行緒數目),如果設定為為 -1,表示對於應該使用的並行量沒有上限設定。如果將其設定為1,則效果和單執行緒一樣.
5. 停止/中斷迴圈
通過呼叫ParallelLoopState例項的Stop方法和Break方法,可以停止和中斷當前迴圈的執行.其中,
Ø Break 告知 Parallel 迴圈應在系統方便的時候儘早停止執行當前迭代之外的迭代.
Ø Stop 告知 Parallel 迴圈應在系統方便的時候儘早停止執行。
程式碼如下:
Parallel.ForEach(list, (int i, ParallelLoopState state) =>
{
if (i == 5)
{
state.Break();
}
Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);
});
其中, ParallelLoopState類的例項由Parallel類自動建立並傳遞到所執行的方法中.所以我們可以直接使用,而不是需要事前申明並例項一個ParallelLoopState物件.
本文轉自風車車 部落格園部落格,原文連結:http://www.cnblogs.com/xray2005/archive/2011/08/30/2159052.html,如需轉載請自行聯絡原作者
相關文章
- 多核時代.NETFramework4中的並行程式設計9—執行緒安全集合類Framework並行行程程式設計執行緒
- parallel: 一個簡單的並行執行Go迴圈的庫Parallel並行Go
- .NET並行程式設計實踐(一:.NET平行計算基本介紹、並行迴圈使用模式)並行行程程式設計模式
- 並行(Parallel)並行Parallel
- Oracle並行操作——並行查詢(Parallel Query)Oracle並行Parallel
- Parallel 並行技術Parallel並行
- WRF WPS多核並行執行並行
- C#並行Parallel程式設計模型實戰技巧手冊C#並行Parallel程式設計模型
- .NET併發程式設計-資料並行程式設計並行
- EXPDP/IMPDP 中的並行度PARALLEL引數並行Parallel
- oracle的Parallel 並行技術OracleParallel並行
- C#並行程式設計:Parallel的使用C#並行行程程式設計Parallel
- 並行閘道器 Parallel Gateway並行ParallelGateway
- 並行處理 Parallel Processing並行Parallel
- 使用.NET並行任務庫(TPL)與並行Linq(PLINQ)充分利用多核效能並行
- .NET併發程式設計-任務函式並行程式設計函式並行
- oracle parallel並行_引數parameter_parallel_max_serverOracleParallel並行Server
- .NET併發程式設計-TPL Dataflow並行工作流程式設計並行
- goroutine的多核並行化,讓出時間片Go並行
- 11G R2中的並行執行,dbms_parallel_execute並行Parallel
- golang runtime實現多核並行任務Golang並行
- 為SSD程式設計(4):高階功能和內部並行程式設計並行
- MYSQL並行複製(parallel replication部署篇)MySql並行Parallel
- fast_start_parallel_rollback和並行rollbackASTParallel並行
- oracle parallel並行及px檢視viewOracleParallel並行View
- 社交網路分析的 R 基礎:(四)迴圈與並行並行
- C#並行,多執行緒程式設計並行集合和PLINQ的例項講解並行執行緒程式設計
- 併發程式設計-8.並行資料結構和並行Linq程式設計並行資料結構
- 使用dbms_parallel_execute來完成DML的並行Parallel並行
- Oracle中的並行系列(二):你設定的並行真的生效了嗎?Oracle並行
- Oracle中的並行Oracle並行
- Oracle資料庫並行機制Parallel ExecutionOracle資料庫並行Parallel
- dbms_mview 並行重新整理 refresh parallelView並行Parallel
- ORACLE ORA-00020與parallel並行OracleParallel並行
- 【oracle】使用DBMS_PARALLEL_EXECUTE並行更新表OracleParallel並行
- mysql 的procedure 中 loop迴圈的用法。MySqlOOP
- 5天玩轉C#並行和多執行緒程式設計 —— 第一天 認識ParallelC#並行執行緒程式設計Parallel
- alter session enable parallel dml 使DML語句並行執行SessionParallel並行