執行緒安全 (Thread-safe)
現代程式設計為了提升效能,通常採用多執行緒的方式執行,但若沒有注意執行緒安全,往往會造成意想不到的錯誤。
假設現在有一個程式有 Main & Timer 兩個 Thread 都會透過 i2c command 存取硬體,模擬的程式碼如下:
執行結果如下,可以發現兩個 Thread 在做底層 i2c Read / Write 時是交錯的,
此時可利用 lock 來保護 Read / Write 的過程中是不會被其他 Thread 中斷的
執行結果如下,可以發現不再有交錯的情況了
假設現在有一個程式有 Main & Timer 兩個 Thread 都會透過 i2c command 存取硬體,模擬的程式碼如下:
using System;
using System.Threading;
namespace ThreadTest
{
class I2cGpu
{
public void NormalRead(int index)
{
Console.WriteLine("{0} ==> NormalRead{1}", Thread.CurrentThread.Name, index);
Thread.Sleep(500);
Console.WriteLine("{0} <== NormalRead{1}", Thread.CurrentThread.Name, index);
}
public void NormalWrite(int index)
{
Console.WriteLine("{0} ==> NormalWrite{1}", Thread.CurrentThread.Name, index);
Thread.Sleep(2000);
Console.WriteLine("{0} <== NormalWrite{1}", Thread.CurrentThread.Name, index);
}
}
class ThreadTest
{
static void Main(string[] args)
{
Thread threadMain = new Thread(MainThread);
threadMain.Name = "Main ";
Thread threadTimer = new Thread(TimerThread);
threadTimer.Name = "Timer";
threadMain.Start();
threadTimer.Start();
}
private static void TimerThread()
{
I2cGpu i2CGpu = new I2cGpu();
for (int i = 0; i < 3; i++)
{
i2CGpu.NormalRead(i);
i2CGpu.NormalWrite(i);
}
}
private static void MainThread()
{
I2cGpu i2CGpu = new I2cGpu();
for (int i = 0; i < 3; i++)
{
i2CGpu.NormalRead(i);
i2CGpu.NormalWrite(i);
}
}
}
}
執行結果如下,可以發現兩個 Thread 在做底層 i2c Read / Write 時是交錯的,
此時可利用 lock 來保護 Read / Write 的過程中是不會被其他 Thread 中斷的
using System;
using System.Threading;
namespace ThreadTest
{
class I2cGpu
{
static object locker = new object();
public void NormalRead(int index)
{
lock (locker)
{
Console.WriteLine("{0} ==> NormalRead{1}", Thread.CurrentThread.Name, index);
Thread.Sleep(500);
Console.WriteLine("{0} <== NormalRead{1}", Thread.CurrentThread.Name, index);
}
}
public void NormalWrite(int index)
{
lock (locker)
{
Console.WriteLine("{0} ==> NormalWrite{1}", Thread.CurrentThread.Name, index);
Thread.Sleep(2000);
Console.WriteLine("{0} <== NormalWrite{1}", Thread.CurrentThread.Name, index);
}
}
}
class ThreadTest
{
static void Main(string[] args)
{
Thread threadMain = new Thread(MainThread);
threadMain.Name = "Main ";
Thread threadTimer = new Thread(TimerThread);
threadTimer.Name = "Timer";
threadMain.Start();
threadTimer.Start();
}
private static void TimerThread()
{
I2cGpu i2CGpu = new I2cGpu();
for (int i = 0; i < 3; i++)
{
i2CGpu.NormalRead(i);
i2CGpu.NormalWrite(i);
}
}
private static void MainThread()
{
I2cGpu i2CGpu = new I2cGpu();
for (int i = 0; i < 3; i++)
{
i2CGpu.NormalRead(i);
i2CGpu.NormalWrite(i);
}
}
}
}
執行結果如下,可以發現不再有交錯的情況了


留言