Chpt 23 비동기 작업 수행
Download
Report
Transcript Chpt 23 비동기 작업 수행
Chpt 23
윈도우 프로세스들은 여러 개의 스레드를 만들어 일을 분담시킴
I/O 처리
병렬 처리
위험 부담 감소
일을 분담을 시켜놓긴 했는데, 전체 흐름은 별개의 흐름의 완성임
별개가 완성되지 않으면 전체가 진행되지 않을 수 있음!
스레드들이 일을 끝마쳤는지, 진행중인지 어떻게 알까?
시스템이 여러가지 일을 한번에 처리하는(것 처럼 보이는) 방법
작업 스레드를 여러 개로 늘려 각자의 스레드를 CPU가 번갈아가면서 수행
Round-Robin, 다단계 큐 스케쥴링
물리적,논리적 CPU 개수가 증가함에 따라 실제로 처리 작업 개수가 증가함
실제로는 CPU가 이 스레드 저 스레드를 돌아가면서 처리해야 하기 때
문에
계속 작업 위치를 변경해야 하는 부담이 발생
스레드를 위한 공간은 계속 할당되고 해당 공간은 잠김
스레드를 만들고 파기하는 일 자체가 로드가 크기 때문에
CLR이 스레드 풀을 만들어 관리
스레드가 종료되면 스레드 풀로 복귀하여 다른 스레드 작업시 대신 투입됨
시스템이 바쁘지 않을 때 파기
▪
스레드 파기가 로드가 커도 어차피 바쁘지 않을 때 파기하므로 시스템 전체의 로드는 문제없음
스레드풀에 작업을 밀어넣는 메소드를 호출에 큐에 작업을 밀어넣음
CPU의 상태에 따라 작업들이 처리되는 순서가 다를 수 있음
static boolean QueueUserWorkItem(WaitCallback callBack);
static boolean UnsafeQueueUserWorkItem(WaitCallback callBack, Object state);
System.Threading.Thread
스레드 생성자를 호출
Public Thread(ParameterizedThreadStart start);
delegate void ParameterizedThreadStart (Object obj);
실제로 스레드 생성은 start를 호출해야 생성됨.
System.Threading.Timer을 이용하여 주기적으로 작업을 수행시킬 수
있음.
가비지 콜렉션 문제
public void Dispose()
public boolean Dispose(Waithandle notifyobject) 로 Dispose 하면 콜백이 일어나는것
을 막음
System.IO.FileStream.Read
동기적 읽기
다 읽기 전까지는 다른 작업을 할 수 없음
언제 끝날 줄 알고?
FileStream.BeginRead
I/O 작업을 함으로써 장치 드라이브에게 일을 위임시킴
IAsyncResult 리턴타입
작업이 등록되었음이 리턴됐지 작업이 끝났음이 리턴된 것이 아님
그렇다면 어떻게 작업들이 끝났는지 알아낼까?
랑데부
제미니 계획
따로 발사된 로켓이 편대비행
Beginxxx , Endxxx
Beginxxx로 작업 큐에 작업을 넣고, Endxxx로 호출하면 해당 작업이 완료될 때 까지
Endxxx 메소드가 대기 상태가 됨. 따라서 Endxxx 메소드가 리턴됐을 때는 항상 작업
이 완료되었음이 보장됨.
같은 IAsyncResult 타입의 인자를 사용해야 함.
Beginxxx과 Endxxx의 리턴타입과 같아야함. 실제로 Endxxx의 반환값은 Beginxxx로
밀어넣은 작업이 리턴해야 하는 반환값을 리턴함.
스레드 폴링
For문을 돌면서 스레드들이 작업을 끝냈는지 물어보고 다니기
부하가 많이 듬
Jeffery Ritcher이 안좋아하는 방법
콜백을 이용한 랑데부
Beginxxx 메소드에 콜백 메소드를 등록하여, 작업이 끝나면 자동으로
스레드 풀에 콜백 메소드를 밀어넣음
위의 내용들이 대부분 I/O(FileStream.BeginRead)에 초점이 맞춰져 있
지만
구조상으로는 단순계산 작업 (포문을 돌면서 통계를 낸다거나)도 가능
비동기 작업 중에 예외가 발생했다면 알려야 함
장치를 읽다가 언플러그 됐다거나
장비를 정지합니다
안부르면 언제 리턴값을 전달해줘야 할지 모르므로 계속 스레드가 들고있게됨
한번 End되면 리소스 해지가 일어날 수 있으므로
CLR이 예외를 자동으로 캐치하여 Endxxx가 호출 될 때 다시 예외를 던
져줌.
처리하지 않는다면
작업을 시켜놨으면 결과를 받아와야함
Endxxx를 반드시 호출해야함
Endxxx를 여러번 호출하면 안됨
Beginxxx와 Endxxx를 할 때 사용한 객체는 동일해야(Equal)한다.
현재 스레드가 가진 정보
권한
더이상의 자세한 설명은 생략한다