자세 한 설명 c\#스 레 드 동기 화
앞의 글 은 다 중 스 레 드 를 만들어 서 프로그램 에 더 잘 응답 할 수 있 도록 하 는 것 을 말 합 니 다.그러나 우리 가 여러 스 레 드 를 만 들 었 을 때 여러 스 레 드 가 공 유 된 자원 에 동시에 접근 하 는 상황 이 존재 합 니 다.이런 상황 에서 우 리 는 스 레 드 동기 화 를 사용 해 야 합 니 다.스 레 드 동기 화 는 데이터(공유 자원)의 손상 을 방지 할 수 있 습 니 다.
그러나 우 리 는 응용 프로그램 을 설계 할 때 라인 동기 화 를 최대한 피해 야 한다.왜냐하면 라인 동기 화 에 문제 가 생 길 수 있 기 때문이다.
1.그것 의 사용 은 비교적 번거롭다.여러 스 레 드 가 동시에 접근 하 는 데 이 터 를 추가 코드 로 둘러싸 고 스 레 드 동기 화 자 물 쇠 를 가 져 오고 풀 어야 하기 때문에 코드 블록 에서 자 물 쇠 를 가 져 오 는 것 을 잊 으 면 데이터 가 손 상 될 수 있 습 니 다.
2.스 레 드 동기 화 를 사용 하면 성능 에 영향 을 줄 수 있 습 니 다.자 물 쇠 를 가 져 오고 방출 하 는 데 시간 이 걸 릴 것 입 니 다.어떤 스 레 드 가 먼저 자 물 쇠 를 가 져 올 지 결정 할 때 CPU 가 조 화 를 이 루어 야 하기 때 문 입 니 다.이런 추가 작업 을 하면 성능 에 영향 을 줄 수 있 습 니 다.
3.스 레 드 가 한 번 에 한 스 레 드 만 자원 에 접근 할 수 있 기 때문에 스 레 드 를 막 을 수 있 고 스 레 드 를 막 으 면 더 많은 스 레 드 가 생 성 될 수 있 습 니 다.그러면 CPU 는 더 많은 스 레 드 를 조정 해 야 할 수도 있 고 성능 에 도 영향 을 줄 수 있 습 니 다.
따라서 실제 디자인 에서 스 레 드 동기 화 를 최대한 피해 야 하기 때문에 우 리 는 공유 데이터,예 를 들 어 정적 필드 를 사용 하 는 것 을 피해 야 한다.
2.스 레 드 동기 화 사용
2.1 자물쇠 사용 성능 에 대한 영향
위 에서 이미 말 했 듯 이 자 물 쇠 를 사용 하면 성능 에 영향 을 미 칠 수 있다.다음은 자 물 쇠 를 사용 하거나 자 물 쇠 를 사용 하지 않 을 때 소모 되 는 시간 을 비교 하여 이 점 을 설명 한다.
using System;
using System.Diagnostics;
using System.Threading;
namespace InterlockedSample
{
//
//
class Program
{
static void Main(string[] args)
{
int x = 0;
// 500
const int iterationNumber = 5000000;
//
// StartNew Stopwatch , , 。
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterationNumber; i++)
{
x++;
}
Console.WriteLine("Use the all time is :{0} ms", sw.ElapsedMilliseconds);
sw.Restart();
//
for (int i = 0; i < iterationNumber; i++)
{
Interlocked.Increment(ref x);
}
Console.WriteLine("Use the all time is :{0} ms", sw.ElapsedMilliseconds);
Console.Read();
}
}
}
운행 결과(이것 은 내 컴퓨터 에서 운행 한 결과)결과 에서 알 수 있 듯 이 자 물 쇠 를 넣 은 운행 속도 가 많이 느 려 졌 다(11 배 197/18).2.2 Interlocked 스 레 드 동기 화 실현
Interlocked 류 는 여러 스 레 드 가 공유 하 는 변 수 를 위해 원자 조작 을 제공 합 니 다.우리 가 다 중 스 레 드 에서 하나의 정 수 를 증가 시 킬 때 스 레 드 동기 화 를 실현 해 야 합 니 다.
변수 추가 작업(+연산 자)은 원자 작업 이 아니 기 때문에 다음 절 차 를 실행 해 야 합 니 다.
1)인 스 턴 스 변수의 값 을 레지스터 에 불 러 옵 니 다.
2)이 값 을 증가 하거나 감소 합 니 다.
3)인 스 턴 스 변수 에 이 값 을 저장 합 니 다.
Interlocked.increment 방법 을 사용 하지 않 으 면 스 레 드 는 앞의 두 단 계 를 실행 한 후에 앞 설 수 있 습 니 다.그 다음 에 다른 스 레 드 에서 모든 세 단 계 를 실행 합 니 다.이때 첫 번 째 스 레 드 는 변수의 값 을 인 스 턴 스 변수 에 저장 하지 않 았 고 다른 스 레 드 는 인 스 턴 스 변 수 를 레지스터 에 불 러 와 읽 을 수 있 습 니 다.(이때 불 러 온 값 은 변 하지 않 았 습 니 다)그래서 우리 가 예상 한 결과 가 아 닙 니 다.이러한 해석 이 Interlocked.Incrediment 방법 과 원자 성 조작 을 잘 이해 하 는 데 도움 이 될 것 이 라 고 믿 습 니 다.
다음은 코드 를 통 해 자 물 쇠 를 추가 하 는 것 과 자 물 쇠 를 추가 하지 않 는 것 의 차 이 를 보 여 줍 니 다.(자 물 쇠 를 추가 하면 성능 에 영향 을 줄 수 있 습 니 다.여기 서 자 물 쇠 를 추가 하여 스 레 드 동기 화 문 제 를 해결 하고 우리 가 기대 하 는 결 과 를 얻 을 수 있 습 니 다)
잠 금 이 없 는 경우:
class Program
{
static void Main(string[] args)
{ for (int i = 0; i < 10; i++)
{
Thread testthread = new Thread(Add);
testthread.Start();
}
Console.Read();
}
//
public static int number = 1;
public static void Add()
{
Thread.Sleep(1000);
Console.WriteLine("the current value of number is:{0}", ++number);
}
}
실행 결과(컴퓨터 에 따라 실행 가능 한 결 과 는 나의 것 과 다 르 지만 모두 예상 치 못 한 결 과 를 얻 었 습 니 다):이러한 문 제 를 해결 하기 위해 서 우 리 는 Interlocked.Incrediment 방법 을 사용 하여 원자의 자체 증가 조작 을 실현 할 수 있다.
코드 는 간단 합 니 다.++number 를 Interlocked.Increment(ref number)로 바 꾸 면 우리 가 예상 한 결 과 를 얻 을 수 있 습 니 다.여기 서 코드 와 실행 결 과 는 붙 이지 않 습 니 다.
어쨌든 Interlocked 클래스 의 방법 은 원자 읽 기와 쓰기 동작 을 수행 합 니 다.
2.3 Monitor 스 레 드 동기 화 실현
위의 상황 에 대해 서도 Monitor.Enter 와 Monitor.Exit 방법 을 통 해 스 레 드 동기 화 를 실현 할 수 있 습 니 다.C\#에서 lock 키 워드 를 통 해 간단 한 문법(lock 은 Monitor.Enter 와 Monitor.Exit 방법 으로 이해 할 수 있 는 문법 사탕)을 제공 합 니 다.코드 도 간단 합 니 다.
using System;
using System.Threading;
namespace MonitorSample
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Thread testthread = new Thread(Add);
testthread.Start();
}
Console.Read();
}
//
public static int number = 1;
public static void Add()
{
Thread.Sleep(1000);
//
Monitor.Enter(number);
Console.WriteLine("the current value of number is:{0}", number++);
// 。
Monitor.Exit(number);
}
}
}
운행 결 과 는 당연히 우리 가 기대 하 는 것 이다.Monitor 류 에 서 는 또 다른 몇 가지 방법 이 소개 되 어 있 습 니 다.다만 주 의 를 끌 수 있 도록 하나의 Wait 방법 은 Wait 방법의 역할 이 뚜렷 합 니 다.어떤 대상 의 자 물 쇠 를 풀 어 다른 스 레 드 가 이 대상 을 잠 그 고 방문 할 수 있 도록 하 는 것 입 니 다.두 번 째 는 TryEnter 방법 입 니 다.이 방법 은 Enter 방법 과 주요 한 차이 점 은 현재 스 레 드 를 막 을 지 여부 입 니 다.한 대상 이 Enter 방법 으로 자 물 쇠 를 가 져 올 때 Exit 방법 으로 자 물 쇠 를 풀 지 않 습 니 다.다른 스 레 드 가 Enter 를 통 해 자 물 쇠 를 얻 으 려 고 할 때 이 스 레 드 는 막 힐 것 입 니 다.다른 스 레 드 가 자 물 쇠 를 풀 때 까지 TryEnter 는 스 레 드 를 막 지 않 습 니 다.구체 적 인 코드 는 쓰 지 않 겠 습 니 다.
2.4 ReaderWriterLock 스 레 드 동기 화 실현
만약 에 우리 가 공유 자원 에 대해 여러 번 읽 어야 할 때 앞에서 말 한 클래스 로 이 루어 진 동기 화 잠 금 은 하나의 스 레 드 만 허용 하고 모든 스 레 드 가 막 힐 것 입 니 다.그러나 이런 상황 에서 켄 은 다른 스 레 드 를 막 을 필요 가 없습니다.동시에 실행 하도록 해 야 합 니 다.왜냐하면 우 리 는 이 때 읽 기 작업 만 하기 때 문 입 니 다.이 때 Reader WriterLock 클래스 를 통 해 읽 기와 병행 을 잘 할 수 있 습 니 다.
데모 코드:
using System;
using System.Collections.Generic;
using System.Threading;
namespace ReaderWriterLockSample
{
class Program
{
public static List<int> lists = new List<int>();
//
public static ReaderWriterLock readerwritelock = new ReaderWriterLock();
static void Main(string[] args)
{
//
Thread t1 = new Thread(Write);
t1.Start();
// 10
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(Read);
t.Start();
}
Console.Read();
}
//
public static void Write()
{
// , 10 。
readerwritelock.AcquireWriterLock(10);
Random ran = new Random();
int count = ran.Next(1, 10);
lists.Add(count);
Console.WriteLine("Write the data is:" + count);
//
readerwritelock.ReleaseWriterLock();
}
//
public static void Read()
{
//
readerwritelock.AcquireReaderLock(10);
foreach (int li in lists)
{
//
Console.WriteLine(li);
}
//
readerwritelock.ReleaseReaderLock();
}
}
}
실행 결과:3.총화
본 고 는 주로 다 중 스 레 드 동기 화 문 제 를 어떻게 실현 하 는 지 소개 하고 스 레 드 동기 화 를 통 해 공유 데이터 의 손상 을 방지 할 수 있 으 나 자 물 쇠 를 얻 는 과정 에서 성능 손실 이 있 기 때문에 디자인 응용 과정 에서 스 레 드 동기 화 사용 을 최대한 줄인다.상호 배척(Mutex),신 호 량(Semaphore),사건 구 조 를 소개 해 야 하 는데 편폭 때문에 여러분 의 읽 기 에 영향 을 줄 까 봐 나머지 내용 은 뒤에 소개 해 드 리 겠 습 니 다.
이상 은 c\#스 레 드 동기 화 에 대한 상세 한 내용 입 니 다.c\#스 레 드 동기 화 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.