ERESTARTSYS가 리눅스 드라이버를 작성하는 동안 사용한 것은?
리눅스 디바이스 드라이버 작성을 위한 차단 I/O 기능에 대해 배우고 있는데 어떤 용도로 사용되는지 궁금합니다.ERESTARTSYS
. 다음을 고려합니다.
전역 변수:
wait_queue_head_t my_wait_q_head;
int read_avail = 0;
device_init():
init_waitqueue_head(&my_wait_q_head);
device_read():
printk("I'm inside driver read!\n");
wait_event_interruptible(&my_wait_q_head, read_avail != 0);
printk("I'm awaken!\n");
device_write():
read_avail = 1;
wake_up_interruptible(&my_wait_q_head);
내가 전화할 때.read()
사용자 공간에서 명령 프롬프트가 호출될 때까지 보류됩니다.write()
역시. 더printk
메시지는 그에 따라 또한 나타납니다.dmesg
. 하지만 몇몇 드라이버들은 이렇게 적혀있습니다.
device_read()의 다른 버전:
printk("I'm inside driver read!\n");
if(wait_event_interruptible(&my_wait_q_head, read_avail != 0))
{return -ERESTARTSYS;}
printk("I'm awaken!\n");
나는 두번째 버전을 테스트했습니다.device_read()
사용자 공간에서 동일한 방법을 사용하고, 결과는 완전히 똑같습니다. 그렇다면, ERESTARTSYS는 무슨 소용이 있습니까?
p/s: 리눅스 Device Driver라는 책을 읽었는데 이해가 안 가요, 누가 예를 들어 설명해줄 수 있나요?
그 전화가 지나면 뭔가가 우리를 깨웠지만, 우리는 무엇을 알지 못합니다.한 가지 가능성은 공정이 신호를 수신했을 가능성입니다.wait_event_interruptible call이 포함된 if 문은 이 경우를 확인합니다.이 진술은 신호에 대한 적절하고 예상되는 반응을 보장합니다. 신호는 프로세스를 깨우는 데 책임이 있을 수 있기 때문입니다(중단할 수 없는 수면 상태였기 때문입니다).신호가 도착했지만 프로세스에 의해 차단되지 않았다면 커널의 상위 계층에서 이벤트를 처리하도록 하는 것이 적절한 동작입니다.이를 위해 드라이버는 호출자에게 -RESTARTSYS를 반환합니다. 이 값은 시스템 호출을 재시작하거나 사용자 공간에 -EINTR을 반환하는 VFS(가상 파일 시스템) 계층에서 내부적으로 사용됩니다.우리는 모든 읽기 및 쓰기 구현에 동일한 유형의 검사를 사용하여 신호 처리를 처리합니다.
출처 : http://www.makelinux.net/ldd3/chp-6-sect-2
-ERESTARTSYS
는 재시작 가능한 시스템 호출의 개념에 연결됩니다.재시작 가능한 시스템 호출은 중단이 있을 때 커널에 의해 투명하게 다시 실행될 수 있는 호출입니다.
예를 들어 시스템 호출에서 절전 모드인 사용자 공간 프로세스는 신호를 받아 핸들러를 실행한 다음 핸들러가 돌아오면 커널로 다시 돌아가 원래 시스템 호출에서 계속 절전 모드로 전환할 수 있습니다.
POSIX API 사용SA_RESTART
플래그, 프로세스는 신호와 연관된 재시작 동작을 정렬할 수 있습니다.
커널에서 기능이 에서 에서 나 할 하면 을 이 에 이 의 할 하면 을 에서 이 에 -EINTR
.그렇지만-EINTR
이 반환되도록 합니다.-1
와 함께errno
으로 설정합니다EINTR
.
만약 당신이 돌아온다면-ERESTARTSYS
대신 시스템 호출을 다시 시작할 수 있음을 의미합니다.ERESTARTSYS
코드가 반드시 사용자 공간에 표시되지는 않습니다.은 로로 됩니다.-1
errno
으로 설정합니다EINTR
(사용자 공간에 분명히 표시됨) 또는 시스템 호출 재시작 동작으로 변환됩니다. 즉, 시스템 호출이 동일한 인수로 다시 호출됨을 의미합니다(사용자 공간 프로세스의 일부에 대한 조치는 없음: 커널은 특별한 재시작 블록에 정보를 저장함으로써 이 작업을 수행함).
이전 단락의 "동일한 인수"에 대한 명백한 문제에 주목하십시오. 일부 시스템 호출은 동일한 매개 변수를 사용하여 다시 시작할 수 없습니다. 왜냐하면 idempotent가 아니기 때문입니다.예를 들어, 나노슬립과 같은 수면 통화가 5.3초 동안 있다고 가정해 보겠습니다.5초 후에 중단됩니다.순진하게 다시 시작하면 5.3초 더 잠을 잡니다.새 매개 변수를 재시작된 호출에 전달하여 남은 0.3초 동안만 절전 모드로 전환해야 합니다. 즉, 재시작 블록의 내용을 변경할 수 있습니다.른를작고에를는이다e다이는를e를른:eutofo의yotss고daek작'-ERESTART_RESTARTBLOCK
값액
두 번째 질문을 다루자면, 무엇이 다른가요?고요은는환만기지을고e?요은는yttteg환ed만eedgn?-ERESTARTSYS
자,은 잘못된 것이기 글쎄요, 왜냐하면 그건 잘못된 거예요. 기상이 신호 때문이라면요!신호가 도착할 때마다 읽은 0바이트를 반환하도록 읽기를 원하십니까?이는 사용자 공간에서 데이터의 끝으로 잘못 해석될 수 있습니다.이런 문제는 신호를 사용하지 않는 테스트 케이스에서는 나타나지 않습니다.
언급URL : https://stackoverflow.com/questions/9576604/what-does-erestartsys-used-while-writing-linux-driver
'programing' 카테고리의 다른 글
프로그래밍 방식으로 "select file(파일 선택)" 대화 상자 트리거 (0) | 2023.09.16 |
---|---|
Angular2 - 앱 외부에서 컴포넌트 기능 호출 방법 (0) | 2023.09.16 |
wordpress .htaccess의 폴더 인덱스 (0) | 2023.09.16 |
GitLab CI 대젠킨스 (0) | 2023.09.16 |
npm - EPERM: Windows에서 작업이 허용되지 않음 (0) | 2023.09.16 |