무한루프와 cpu사용량....

dalmuri4551의 이미지

예를들어 아래와 같은 프로그램이 있다면....

#include <stdio.h>

int get_message(void) {
    // 이 함수는 특정 메시지큐에 데이터가
    // 들어오면 1을 반환하고 없으면 0을 반환
}

int todo(void) {
    // 실제 이 프로세스가 처리할 작업내용
    return 0;
}

int main(void)
{
    while(1) {
        if ( get_message() == 1) {
              todo();
        }
    }

    exit(0);
}

get_message() 함수가 1을 반환할 경우 todo()를
실행하고 그렇지 않으면 다시 get_message() 함수를
호출합니다. (즉, 특정 메시지큐에 데이터가 들어오는지 리슨하는 역활)
그런데..문제는 만약 get_message()함수가 계속 0을 반환하게 되면
while(1)문이 계속 돌기 때문에 cpu사용량을 거의 다 먹어버립니다.

이 문제를 해결하기 위해서 아래와 같이 sleep(1)을 주었는데요.
cpu 사용량은 현져히 떨어졌지만, 빨라도 1초에 한건밖에 처리를 못하게
되어 버립니다..만약 특정 메시지큐로 들어오는 메시지의 양이 초당 한건
이상이라면 꺼내서 처리하는 이 프로세서에서 초당 한건밖에 처리를 못시키니
결국 메시지큐가 꽉차버리게 되지 않을까 싶습니다.

    while(1) {
        if ( get_message() == 1) {
              todo();
        }
        sleep(1);
    }

어케 처리하면 좋을까요....에궁...

qprk의 이미지

man usleep

멋진남자...

kuma의 이미지

sleep 을 사용하셨군요. 당연 1초에 1건 입니다.

usleep 을 사용하세요

acetcom의 이미지

좀 더 나이스(?) 방법을 위해서는 thread-safe하고 데이터가 없을때,
blocking되는 queue를 만드는 것이 좋을 것 같습니다.

그렇다면 다음과 같은 코드가 되겠죠.

while(1)
{
       if (get_message() != is_empty)
       {
               todo();
       }
}

이렇게 하고, 다른 Thread가 put_message()를 하면 됩니다.
sleep이 없어도, get_message()가 blocking되어 있으므로,
메시지 큐에 버퍼가 찰 때까지 계속 wait하게 될 것입니다.

제가 예전에 올린 글을 찾아보시면, 예제 소스를 구하실 수 있을 것입니다.

그럼.

mach의 이미지

좋은 답변들이 많았습니다요.
저도 하나 제안하자면 아래와 같습니다.

Quote:
o If (msgflg&IPC_NOWAIT) is 0, the calling process will
suspend execution until one of the following occurs:

o A message of the desired type is placed on the
queue.

o The message queue identifier msqid is removed
from the system (see msgctl(2)); when this
occurs, errno is set equal to EIDRM and -1 is
returned.

o The calling process receives a signal that is to
be caught; in this case a message is not
received and the calling process resumes execu-
tion in the manner prescribed in sigaction(2).


Sun기종의 man페이지입니다.
Quote:
man msgrcv

특정 메시지큐라면(대상이 하나라면) 위의 매뉴얼대로 코딩하면 되겠습니다.
그럼, 커널 스케쥴러 수준에서 블록킹(suspend)될테고, CPU를 잡아먹지는
않습니다. 이후 특정메시지큐에 값이 들어오면 자연스럽게 깨어나겠지요.(사실,
커널이 깨우지요.)
또한 모든 유닉스 시스템호출은 블록킹(커널수준)인 경우, 임의의 시그널을
해당 프로세스가 수신하게되면 그 시스템호출에서 탈출된다는 점도
관과하지 마시기 바랍니다.
* man page잘 보세요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.