Thread同期/しきい値
🚀 同期コンセプト
マルチスレッド環境では、複数のスレッドが1つの共有データを使用するため、1つのスレッドにデータを格納する場合、別のスレッドからデータを読み込むか、反対のスレッドからデータを読み出すなど、多くの問題が発生する可能性があります.したがって、データを格納する過程では、データの読み出しを禁止しなければならず、データの読み出し過程では、データを書き込むことができない.この場合、1つのスレッドが動作中に別のスレッドに干渉されるスレッドの同期を防止することが必要である.
同期臨界領域では、スレッドがリソースを順番に使用します.
🚀 同期メソッド
🔥 Interlocked
🔥 Interlocked
C#のInterlockedは、マルチスレッド共有変数に対して原子レベル演算を提供します.
これは臨界領域内の固有資源変数の原子性を保証する.
static int num = 0;
static void Main(string[] args)
{
Task t1 = new Task(Thread1);
Task t2 = new Task(Thread2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(num);
}
static void Thread1()
{
for(int i = 0; i< 1000000; i ++)
{
num++;
}
}
static void Thread2()
{
for (int i = 0; i < 1000000; i++)
{
num--;
}
}
上のコードでは、共有リソースnumにアクセスするスレッドが2つあります.最初のスレッドは百万回1増加し、2番目のスレッドは百万回1減少するため、numの値は2つのスレッドの終了時に0になる可能性があります.実際にはスペクトル外の値が出力されます.これは,2つのスレッドが並列に進行し,資源の原子性を保証できないためである.従って、原子性を保証するために、共有リソースnumでインターロックを使用する必要がある.
static int num = 0;
static void Main(string[] args)
{
Task t1 = new Task(Thread1);
Task t2 = new Task(Thread2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(num);
}
static void Thread1()
{
for(int i = 0; i< 1000000; i ++)
{
Interlocked.Increment(ref num);
}
}
static void Thread2()
{
for (int i = 0; i < 1000000; i++)
{
Interlocked.Decrement(ref num);
}
}
上記のコードのように,クラスの増分と増分をロックすることで原子性が保証される.このときの実行結果は、出力の値が予想値と同じであることがわかります.
🔥 Lock
class Program
{
static int Count = 0;
static System.Object lockThis = new System.Object();
static void Print()
{
lock (lockThis)
{
for(int i =0; i< 5; i++)
{
Count++;
Console.WriteLine(Count);
}
}
}
static void Main(string[] args)
{
Thread thread1 = new Thread(new ThreadStart(Print));
Thread thread2 = new Thread(new ThreadStart(Print));
Thread thread3 = new Thread(new ThreadStart(Print));
Thread thread4 = new Thread(new ThreadStart(Print));
thread1.Start();
thread2.Start();
thread3.Start();
thread4.Start();
}
}
🔥 Moniter
class Program
{
static int Count = 0;
static System.Object moniterlock = new System.Object();
static void Print()
{
Monitor.Enter(moniterlock);
try
{
for(int i = 0; i<5; i++)
{
Count++;
Console.WriteLine(Count);
}
}
finally
{
Monitor.Exit(moniterlock);
}
}
static void Main(string[] args)
{
Thread thread1 = new Thread(new ThreadStart(Print));
Thread thread2 = new Thread(new ThreadStart(Print));
Thread thread3 = new Thread(new ThreadStart(Print));
Thread thread4 = new Thread(new ThreadStart(Print));
thread1.Start();
thread2.Start();
thread3.Start();
thread4.Start();
}
}
Ref https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS1669525805 https://neohtux.tistory.com/220?category=620074
https://scvtwo.tistory.com/67
Reference
この問題について(Thread同期/しきい値), 我々は、より多くの情報をここで見つけました https://velog.io/@uchang903/Thread-동기화-임계-영역-Interlocked-Lock-Moniterテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol