Coding4Fun: 讓Windows桌面凍結的.NET程式
| | 3 | | 12,999 |
在Huan-Lin學習筆記看到一篇文章 -- C# 學習筆記:多執行緒 (3) - 優先順序。用.NET跑多執行緒對我不算陌生,但卻一直沒注意到.NET的Process跟Thread的Priority是可以調整的。.NET執行緒預設的優先權是Normal,而Windows核心層次的作業(例如滑鼠、鍵盤訊息處理)多半能擁有更高的優先權,無怪乎過去就算寫.NET程式如何搾乾CPU,Windows的基本操作仍能維持順暢。
學到這招讓我動起邪惡的念頭 -- 來寫支可以凍結Windows桌面的.NET程式吧!
做法很簡單,Process及Thread的優先權都拉到最高,一口氣開八條Thread用空轉的while迴圈吃光CPU。為了比較差異,高優先權模式可透過參數決定是否啟動。程式如下:
排版顯示純文字
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
namespace SystemHang
{
class Program
{
static void Main(string[] args)
{
//由傳入參數決定要不要讓Windows卡卡
bool freeze = (args.Length > 0 && args[0] == "freeze");
var p = Process.GetCurrentProcess();
//卡卡模式時,將Process優先等級拉到RealTime
//註: 實務上幾乎沒有需要設定RealTime的情境(叔叔有練過,小朋友不要學)
if (freeze)
p.PriorityClass = ProcessPriorityClass.RealTime;
//建立八條Thread,就算i7有四核八緒的也要趕盡殺絕
Thread[] threads = new Thread[8];
//使用ManualResetEvent做執行緒同步
ManualResetEvent[] waits = new ManualResetEvent[threads.Length];
//設定刑求時間10秒
DateTime timeUp = DateTime.Now.AddSeconds(10);
for (int i = 0; i < threads.Length; i++)
{
var wait = waits[i] = new ManualResetEvent(false);
threads[i] = new Thread(() =>
{
//於時限內形成空迴圈,讓條件比對耗盡CPU資源
while (DateTime.Now.CompareTo(timeUp) < 0)
{
//什麼都不做,讓迴圈快速轉動
}
//通知執行完畢
wait.Set();
});
//卡卡模式時,指定執行緒優先等級為Highest
if (freeze)
threads[i].Priority = ThreadPriority.Highest;
//啟動執行緒
threads[i].Start();
}
//等待所有執行緒執行完畢
WaitHandle.WaitAll(waits);
Console.WriteLine("Done!");
}
}
}
實測結果如下:

程式跑了兩次,執行期間8顆CPU負載全滿,差別在於第一次使用預設優先權,滑鼠還能自由移動,下方的Up Time也如常累計;而第二次將優先權提高後,滑鼠很難移動,而下方的Handles、Threads、Processes、Up Time等統計停止更新,CPU的負載曲線圖表也不動,直到程式結束才恢復。
無聊的小實驗,可以看出優先權高低造成的影響,也由此可知: 除非你有很好的理由,沒事別提高Thread優先權,只會惹人嫌。
Comments
# by 小黑
黑大真是逗趣
# by gattaca
很多設計師都會開Thread, 但是對於共有資源的競爭(例如UI介面的變化)或是執行順序, 都是以 "理想狀況" 去設計, 從未思考是否可歸納為生產者消費者問題, 埋下一堆執行時期的地雷, 請問你如何避免團隊成員亂開Thread? 我目前是規定若有競爭問題必須以這種方式實做www.cnblogs.com/mgen/archive/2012/05/08/2489955.html
# by Jeffrey
to gattaca, 或許是多緒爭奪UI的情境遇得不多,我沒有太多踩到執行期踩地雷的經驗(不過很願意聽你的分享),少數遇到多緒搶餵資料給UI的情況,我傾向在中間加一個Queue,資料提供者塞資料進Queue,UI主動依自己的節奏由Queue抓資料進行更新,概念有一點點接近你提的生產者消費者模式,但沒有Block機制,適用於較簡單的情境。