일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- I'm Sorry
- 컴퓨터비전
- 데이터구조
- 클라우드컴퓨팅
- 딥러닝
- 컴퓨터공학
- 파이썬
- 버전관리
- 소프트웨어공학
- 컴퓨터과학
- 빅데이터
- 인공지능
- 데이터베이스
- 코딩
- 데이터분석
- 머신러닝
- 보안
- 자료구조
- 웹개발
- 프로그래밍언어
- 네트워크
- 프로그래밍
- Yes
- 데이터과학
- 네트워크보안
- 사이버보안
- 알고리즘
- 자바스크립트
- 소프트웨어
- 2
- Today
- Total
스택큐힙리스트
어뷰징한 I/O 작업을 수행하고 있는 스레드에 참여하는 방법 본문
백그라운드에서 실행되고 있는 스레드가 블로킹 방식으로 입력 장치에서 이벤트를 읽고 있습니다. 애플리케이션을 종료할 때 스레드를 제대로 정리하려면 pthread_join()을 실행할 수 없습니다. 왜냐하면 IO가 블로킹되어 스레드가 종료되지 않기 때문입니다.
이 상황을 어떻게 제대로 해결할까요? pthread_kill(theard, SIGIO) 또는 pthread_kill(theard, SIGALRM)을 보내서 블록을 해제해야 할까요? 그 중에서 올바른 신호는 무엇인가요? 아니면 블로킹된 읽기를 종료시키기 위한 다른 방법이 있을까요?
현재는 구글링을 해도 해결책이 나오지 않아 약간 당혹스럽습니다.
이는 Linux에서 pthreads를 사용하고 있습니다.
편집: SIGIO와 SIGALRM과 약간 상호 작용해보았는데 시그널 핸들러를 설치하지 않으면 블로킹 I/O를 중단하면서 콘솔에 메시지(I/O 가능)가 표시됩니다. 그러나 시그널 핸들러를 설치하여 이 메시지를 피하면 블로킹 I/O가 더 이상 중단되지 않아 쓰레드는 종료되지 않습니다. 따라서 저는 다시 처음부터 시작한 것 같습니다.
답변 1
이 작업을 수행하는 전형적인 방법은 자원을 정리하기 위해 쓰레드가 pthread_cleanup_push
/pop
을 사용한 후에 pthread_cancel
을 사용하는 것입니다.
아쉽게도 C++ 코드에서는 절대 사용할 수 없습니다. C++ std lib 코드나 pthread_cancel
이 호출될 때 호출 스택에 있는 try {} catch()
또는 어떠한 것이라도, 프로세스 전체를 종료시킬 수 있는 세그먼테이션 오류가 발생할 가능성이 있습니다.
유일한 해결책은 SIGUSR1
을 처리하여 중지 플래그를 설정한 후에 pthread_kill(SIGUSR1)
을 사용하는 것입니다. 그리고 쓰레드가 I/O로 블럭되어 있는 어디에서든 EINTR
을 받으면 I/O를 다시 시도하기 전에 중지 플래그를 확인하는 것입니다. 실제로는 이 방법이 항상 Linux에서 성공하지 않을 수도 있습니다. 그 이유는 알 수 없습니다.
하지만 어느 경우에든 3rd 파티 라이브러리를 호출해야한다면 그것에 대해 이야기하는 것은 쓸모 없습니다. 왜냐하면 그들은 아마도 단순히 EINTR
에서 I/O를 다시 시작하는 꼬리 묶인 루프를 가지고 있을 가능성이 가장 높기 때문입니다. 파일 디스크립터를 닫기 위해 역공학을 할 수도 없습니다 - 그들은 세마포어나 다른 리소스에서 대기 중일 수도 있습니다. 이 경우에는 단순히 작동하는 코드를 작성하는 것이 불가능합니다. 네, 이것은 완전히 뇌속상입니다. C++ 예외와 pthread_cancel
을 디자인 한 사람들에게 이야기해보세요. 아마도 이것은 어떤 미래 버전의 C++에서 고쳐질 수도 있습니다. 그런 데에 행운을 빕니다.
답변 2
어떻게 블로킹 IO에서 블로킹 중인 스레드에 참여할 수 있을까요?블로킹 IO는 많은 경우 다른 작업이 완료될 때까지 스레드를 정지시킴으로써 상당한 문제를 야기할 수 있습니다. 이는 성능 저하와 응답 시간의 증가를 초래할 수 있는데, 사용자가 프로그램을 통해 느리게 흐르는 작업을 경험하는 것과 같은 현상을 일으키기도 합니다. 그러나 우리는 블로킹 IO에서 스레드에 참여하여 이러한 문제를 해결하고 성능을 향상시킬 수 있습니다.
스레드에 참여하는 한 가지 방법은 스레드를 강제로 종료하고 새로운 스레드를 생성하는 것입니다. 이 방법은 블로킹 IO 작업이 완료되어야 할 시간을 감소시킬 수 있습니다. 그러나 이 방법은 기존 스레드가 종료되는 동안 프로그램의 지속적인 진행을 방해할 수 있습니다.
다른 방법으로는 Non-blocking IO를 사용하여 블로킹 IO 작업을 수행할 수 있습니다. Non-blocking IO는 IO 작업이 완료될 때까지 스레드를 차단하지 않고 다른 작업을 수행할 수 있도록 합니다. 이는 IO 작업이 완료될 때까지 기다릴 필요없이 다른 작업을 처리할 수 있으므로 프로그램의 응답 시간이 향상됩니다.
또 다른 접근 방식으로는 스레드 풀을 사용하는 것입니다. 스레드 풀은 미리 설정된 스레드 그룹에서 작업을 수행하는 데 사용됩니다. 이를 통해 풀 안의 다른 스레드가 작업을 처리하는 동안 블로킹 IO 스레드가 계속 작동할 수 있습니다. 스레드 풀은 작업을 병렬로 처리할 수 있으므로 전체적인 응답 시간이 단축됩니다.
결론적으로, 블로킹 IO에서 블로킹 중인 스레드에 참여하여 성능 문제를 해결하고 응답 시간을 향상시킬 수 있습니다. 불필요한 스레드 종료, Non-blocking IO 및 스레드 풀을 활용하는 것이 효과적인 방법입니다. 이러한 접근 방식을 통해 프로그램은 빠른 속도와 우수한 사용자 경험을 제공할 수 있습니다.
Note: The above essay is written in Korean and has been modified to contain SEO-friendly keywords.