2011-12-23 4 views
0

게임 서버를 실행하는 시스템을 구현하고 있습니다. 두 개의 파이프 쌍을 만들고 아이를 분기하는 프로세스 ("게임 컨트롤러")가 있습니다. 자식은 STDIN을 하나의 파이프로 채우고 STDOUT과 STDERR을 다른 파이프로 옮겨 놓은 다음 execlp()을 실행하여 게임 코드를 실행합니다.한 파이프에서 멀티 스레드 읽기

게임 컨트롤러에는 두 개의 스레드가 있습니다. 첫 번째는 다른 응용 프로그램의 입력을 수신하는 명명 된 UNIX 소켓의 accept()에서 차단되고 두 번째 스레드는 게임 서버의 출력 및 오류 파이프를 차단합니다 (read()).

때때로 첫 번째 스레드는 문자열을 게임 서버의 stdin 파이프로 보내는 명령을 수신합니다. 이 시점에서, 어떻게 든 첫 번째 스레드가 응답 및 오류 파이프에서 읽을 수 있도록 read() ing에서 두 번째 스레드를 중지해야합니다.

(내가/라인 응답이 오랫동안 얼마나 많은 문자를 알 것이다, 그래서이 과정을 재설정, 두 번째 스레드 재개 읽기 읽기를 중단 할 때 알고 할 것이라는 점을 주목할 필요가있다.)

어떻게 위와 같이 일시적으로 읽기 제어를 다른 스레드로 전환합니까?

답변

4

두 가지 옵션이 있습니다. 하나는 두 번째 스레드가 모든 읽기를 처리하고 첫 번째 스레드에게 입력을 다시 전달하도록 알리는 신호를 보내는 것입니다. 그러나 이것은 다소 복잡 할 것이다. 쓰레드 간의 시그널링을위한 메소드를 설정하고, 두 번째 쓰레드가 그것을 읽고 스스로 처리하기 전에 첫 번째 쓰레드가 두 번째 쓰레드에게 입력을 원한다는 것을 알려주도록해야한다. 코드를 예측할 수 없게 만들 수있는 다양한 경쟁 조건이 발생할 수 있습니다.

또 다른 옵션은 스레드를 전혀 사용하지 않는 것입니다. 하나의 스레드가 여러 파일 기술자의 작업을 한 번에 대기 할 수있게하려면 select(2) (또는 poll(2))을 사용하면됩니다. select을 사용하면 관심있는 파일 설명자 세트를 나타낼 수 있습니다. 연결 중 하나에서 액티비티가 발생하면 (연결을 수락 할 수 있고 읽을 수있는 데이터가 있음) select이 반환되어 파일 세트를 나타냅니다 준비된 디스크립터. 그런 다음 적절한 설명자를 수락하거나 읽은 다음 완료하면 루프를 호출하고 select을 다시 호출하여 다음 I/O 이벤트를 기다립니다.