리눅스 임베디드 장비에서의 usleep이 cpu 제어권을 잃어 버리는 문제
글쓴이: raphael4 / 작성시간: 수, 2013/11/13 - 5:41오후
linux kernel 2.6.x 올라가 있는 장비에서
쓰레드 4개를 돌리는 프로그램을 만들어 쓰는데
가끔씩 장비가 멈추더군요
디버깅을 해봤더니 usleep 을 쓰는 부분에서 쓰레드가 cpu제어권을 못 돌려받아
영원히 정지된 상태 처럼 보였습니다
usleep이 문제가 많은것은 알고 있지만 cpu제어권을 영원히 잃어 버리는 문제는 처음보는거라
굉장히 당황스러운데
여기서 usleep 관련된 글을 검색해서 찾아 보고는 있는데
nanosleep을 써도 같은 문제가 발생 되더군요
근본적인 문제를 찾아 보려고 하는데
어디서 부터 접근해봐야 할지 모르겠습니다
usleep이 cpu 제어권을 잃어 버리는 현상에 대해 자세한 정보를 알고 싶습니다.
Forums:
gilgil.net
sleep 종류의 함수 call로 인해서 해당 스레드가 cpu 제어권을 영원히 잃어 버린다는 얘기는 금시초문인데요. timeout을 너무 크게 주었다면 몰라도...
www.gilgil.net
자답아닌 자답입니다
한 스레드가 sleep을 자주 써 잦은 cpu 제어권을 잃어 버리고
다른 스레드가 빠른 loop문을 가지고 있다면
제어권을 못 돌려 받아 멈춘것같은 현상이 일어 나는듯 합니다
빠른 loop문에 usleep(10) 같이 스레드 제어권 넘겨주는 부분을 만들어 주면
어느정도 해결되는것 같습니다
자세한 원리는 저도 모르겠어서
지나가시는 전문가님이 보신다면 자세한 설명 부탁드립니다
...
이유는 말씀하신 것과 같습니다. sleep이라는건 일단 제어권을 양보하고 나서 다음에 자기 차례가 왔을때 주어진 시간이 흘렀는가를 체크하기 때문에 다른 스레드에서 아예 제어권을 넘기지 않으면 턴이 늦어지는 것이 당연합니다. 이거는 운영체제가 멀티 태스킹을 어떻게 구현했느냐에 달렸으니 플랫폼에 따라 이런 경향이 더 심해질수도 있고 덜할 수도 있겠죠. 아시다시피 단순히 빠른 loop를 가지고 있어서라기보단 그 루프 안에서 제어권을 넘기는 부분이 없어서 그런 것.
만약 그 루프 부분이 퍼포먼스가 중요한 부분이라면 무조건 usleep을 하지 마시고 시간을 측정한다든지 카운트를 하는 식으로 조건부로 usleep을 하게 하면 도움이 될것입니다.
--
자세한 설명 감사드립니다
사실 많이 미심쩍었는데 친절하게 설명해주셔서 묵은 체증이 내려간듯 시원합니다
정말 감사드립니다
말씀하신데로 그 루프 부분이 퍼포먼스가 중요한 스레드인데 제가 생각이 짧았습니다
다른 장비의 메시지를 실시간으로 받기위한 스레드인데
usleep(10)을 주고나니 메시지를 놓치는 경우가 생기더군요
굉장히 짧은 시간이라 괜찮을줄 알았는데 생각이 짧았습니다
언제 올지 모르는 메시지를 받기위해 무한 루프를 돌면서 체크해야 하는데
usleep 을 주면 안되겠더군요
시간을 측정한다고 하더라도 usleep을 하게 되는 그 순간 메시지를 받게 되면 아무 소용 없어지니
차라리 다른 스레드의 usleep을 다 빼야 되나 참 난감합니다
근본적인 문제는 리눅스는 애초에 fine
근본적인 문제는 리눅스는 애초에 fine responsiveness를 위해 설계된 커널이 아니기 때문이죠. RTLinux 를 쓰지 않으면 어느 정도의 둔감한 반응성은 감수할 수 밖에 없을 거라 생각이 듭니다.
usleep()를 주는 순간 커널은 다른 쪽에 제어권을 넘기고, 그 쪽에서 제어권을 풀지 않는 이상 어느 정도의 시간 동안에는 이쪽은 먹통이 될수 밖에 없죠. 10 us 이 아니라 거의 수십 ms 는 휙 지나가 버릴 겁니다. 그러면 무한 루프를 돌 때 수십 s 는 순식간에 지날갈테지요.
세마포를 날려서 잠깐 for loop를 돌고 세마포를 도는 함수를 만들어 보세요. semaphore 도 일종의 제어권을 놓는 기능을 하긴 하는데 다른 쓰레드에 제어권을 넘기는 것이라 응답성은 좀 빠를 거라 봅니다.
댓글 달기