소켓 프로그램 CPU 점유 문제..

gowithsky의 이미지

안녕하세요.

소켓프로그램을 만들어서 리눅스에서 돌리고 있는데요,
시간이 지날수록 CPU점유율이 계속 올라갑니다..
프로그래밍의 문제인것 같긴 한데..잘 모르겠네요..ㅠㅠ

어떤 상황에서 이런 현상이 발생할 수 있나요?
..무한루프같은건 없어보이는데..........

이틀동안 돌리면 거의 99%가 되네요..
고수님들 도와주세요...........

stoneshim의 이미지

글쎄요... 좀 막연하군요.

간단하게라도 소스를 올려서 함께 검토하는게 좋을것 같네요.

개인적으로는 select()나 poll() 사용시에 timeout을 0로 하는 경우가 아니면 cpu 점유율이 그렇게 많이 올라간 적은 없습니다.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

alsong의 이미지

select나 recv 에러에 의한 무한루프가 발생하지는 ...

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

sangheon의 이미지

아주 짧은 시간동안 만이라도 usleep()으로 쉬게 해주시면 효과가 있을 겁니다.

--

Minimalist Programmer

partout의 이미지

stoneshim wrote:
글쎄요... 좀 막연하군요.

간단하게라도 소스를 올려서 함께 검토하는게 좋을것 같네요.

개인적으로는 select()나 poll() 사용시에 timeout을 0로 하는 경우가 아니면 cpu 점유율이 그렇게 많이 올라간 적은 없습니다.

select를 쓰신 경우라면 이 분 말씀이 옳은 것 같습니다.

여기에 약간의 보충 설명을 하겠습니다.
리눅스의 select 콜은 다른 기타 유닉스 시스템의 select 콜과는 약간
다르게 동작합니다.

Quote:
int select(int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

위에 인용한 것이 리눅스 시스템에서의 select 콜의 프로토타입인데...
다른 유닉스와는 다르게 timetout이 const 형이 아닙니다.
기타 유닉스에서는 time이 expire되어서 select 콜을 빠져나온 경우에도
timeout의 값이 변하지 않지만... 리눅스의 경우에 time이 expire된 경우
timeout의 값이 0으로 설정되는 걸로 알고 있습니다.
그래서, select 함수를 호출하기 이전이나 부른 직후에 timeout값을 다시
제대로 초기화시켜 주지 않으면.. select에서 제대로 걸리지 않아서..
CPU를 엄청 잡아 먹습니다.

어찌나 졸린지..~~

partout의 이미지

bookworm wrote:
아주 짧은 시간동안 만이라도 usleep()으로 쉬게 해주시면 효과가 있을 겁니다.

괜찮은 방법이지만...
usleep 함수의 사용은 피하는 게 좋을 거 같네요.
usleep 함수의 경우 Thread-Safe 하지 않습니다.

어찌나 졸린지..~~

송지석의 이미지

partout wrote:
bookworm wrote:
아주 짧은 시간동안 만이라도 usleep()으로 쉬게 해주시면 효과가 있을 겁니다.

괜찮은 방법이지만...
usleep 함수의 사용은 피하는 게 좋을 거 같네요.
usleep 함수의 경우 Thread-Safe 하지 않습니다.


옷 그런가요?
그러면 thread에서 잠깐 쉬고 싶을 때 어떻게 하면 될까요?
제 어플이 thread 내에서 usleep을 자주 사용합니다.
mp3에 데이터를 써주는데 중간중간 쉬어야 하거든요. write에서 너무 오래 블럭되면 안되기에. 처음 잡은 구조상 그렇게 되어있다는...
partout의 이미지

간단하게 select의 timeout 기능을 이용하는 방법이 있습니다.
더 좋은 방법이 있는지는 모르겠네요.

void sleep_ext(int sec, int usec)
{

    struct timeval tv;

    tv.tv_sec = sec;   // sedconds
    tv.tv_usec = usec;  // microseconds


    select(0, NULL, NULL, NULL, &tv);
}

대충 이 정도로 구현해서 쓰시면 될 거 같습니다.

어찌나 졸린지..~~

송지석의 이미지

음..

소켓에다가는 select 타임아웃을 사용하는데요.

mp3에 넣는 부분은 커스텀으로 짠 것인데 select 타임아웃이 먹지 않을 거라고 들어서.. (블럭 드라이버로 짠 게 아닌 것 같은데.. 말이죠. cat my.mp3 >/dev/mp3 하면 플레이가 됩니당)

드라이버는 nonblock으로 되어있어서 (이 표현이 맞는 지 모르지만) write하면 쓴만큼 리턴하고 다 못써도 바로 리턴하거든요.

일단 무한루프로 원하는만큼 쓸 때까지 써버렸더니 점유율이 엄청 올라가고.. 드라이버가 뻗었었나 했었습니다. (이건 작년 일이라 기억이.. -_- )

쓰는 도중 드라이버 내부 버퍼가 차서 못 쓰면 usleep(0) 했더니 응답이 느려서 음이 뚝뚝 끊기더군요.

그래서 드라이버 구조를 바꿔서 자주 호출해도 괜찮도록 만들어서 썼습니다. 물론 쓸 양을 다 쓴다음에는 usleep(0)으로 쉬어주고요.

뭔가 더 좋은 방법이 있을 지..

그냥 select를 사용해도 될까요? select를 사용하려면 드라이버를 바꿔야 할까요? select를 지원하려면 드라이버에서 어떤 지원을 해줘야 하는 지 몰라서 말입니다.

아님 다른 방법이 있는 걸까요?

아시는 분 코멘트 부탁드립니다.

========================================
옷 위의 코드를 제대로 안보고 썼더니 다른 내용이었군요. -- 죄송합니다.

select에 타임아웃을 이용한다라. 음. 그렇군요.

음 그래도 위에 잘못 알고 쓴 내용은 그냥 남겨두겠습니다.

icmplayer의 이미지

Quote:
thread 내에서 usleep을 자주 사용합니다

usleep은 man page보시면 아시겠지만 obsolete죠.
저도 non blocking sysread할뗀 nanosleep을 씁니다. 요놈 쓰면 signal도 안 없어지고 괜찮거든요.

그리고 select 쓰실뗀 위의 어떤 분이 말씀하신 것 처럼 timeout을 업데이트 시킬 경우가 있는데 pselect은 안 그렇습니다.
이것도 man page...

The select function may update the timeout parameter to indicate how much time was left.
The pselect function does not change this parameter

partout의 이미지

훔.. nanosleep이란 게 있었군요...

어찌나 졸린지..~~

mamiere의 이미지

답이 될지 모르겠네요.

점점 올라간다는 점을 주의 깊게 확인해 보시기 바랍니다.

무슨 얘기 인가 하면요....

에러나 무한 루프에 의한 경우는 갑자기 올라 가게 됩니다.

그러나 점점 올라간다는 것은 프로세스의 수가 증가하고 있다는 것을 의미 합니다.

자식 프로세스는 개개가 Thred로 작동하니, Thred의 수가 증가하는 것이 아닌가 싶네요.

한번 일정 시간동안 CPU의 점유율을 기록해 보시면 도움이 될듯 싶네요.

반갑구요, 좋은 시간들 되시길 바랍니다.

최종호의 이미지

송지석 wrote:
음..

소켓에다가는 select 타임아웃을 사용하는데요.

mp3에 넣는 부분은 커스텀으로 짠 것인데 select 타임아웃이 먹지 않을 거라고 들어서.. (블럭 드라이버로 짠 게 아닌 것 같은데.. 말이죠. cat my.mp3 >/dev/mp3 하면 플레이가 됩니당)

드라이버는 nonblock으로 되어있어서 (이 표현이 맞는 지 모르지만) write하면 쓴만큼 리턴하고 다 못써도 바로 리턴하거든요.

select(0, NULL, NULL, NULL, &tv);

은 어떤 특정 파일디스크립터를 대상으로 하는 것이 아니고

아무런 파일디스크립터도 지정을 안 하기 때문에

코드상에서 임의로 1초 미만의 timeout을 걸때 사용하던 방식입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.