쓰레드로 돌리는 프로그램에서의 동기화...

pleasantman의 이미지

Thread의 동기화 문제입니다.
쓰레드는 약 4개 입니다.
각각의 쓰레드에서 log를 시각정보와 같이 만들어 냅니다.
각각의 쓰레드는 select / while / while / select로 돕니다.

각 쓰레드의 log는 프로그램 전체의 공유 버퍼인 buffer1과 buffer2에 저장됩니다.
buffer1이 다차면 파일에 기록하고 그 동안에는 buffer2에 체워집니다.
헌데 시각정보를 담다 보니 시각정보가 역전된 넘들이 보입니다.
각각의 쓰레드의 루프 부분에 일정한 딜래이를 주면(약 usleep(10000))
시각역전은 보이지 않습니다 그러나 이 정도의 딜래이면 프로그램이 전체적으로
너무나 느려져 제대로 성능이 내기 어렵습니다.
( 머 원래 설계가 엉망인 점이 더 큰 이유일 겁니다만... )

mutex같은 걸 사용하는 것도 생각해 봤는데.. 어째든 기다려야 하는 상황이라서..
혹 이런 일 없이 하는 방법이 있을까요? 여러값으로 delay를 줘봤는데..
10ms에서만 이런 일이 없던군요.. mutex로 최소한의 기다림으로 해결할 수 있었으면
좋겠습니다. 방법이 없을까요? 밑에는 3개만 그려봤습니다.

- 어설픈 Thread 사용자 -


thread 1
    while
    {
        buffer1 기록
        or
        buffer2 기록
    }
    
thread2
    while
    {
        file 쓰기  buffer1
        or
        file 쓰기  buffer2
    }

tread_main
    thread1 생성
    thread2 생성
    
    while
    {
        buffer1 기록
        or
        buffer2 기록
    }
kukuman의 이미지

여기선 buffer1, 2에 기록할 때에 mutex를 사용하시면 될 것 같습니다...

Be at a right place at a right time...

pleasantman의 이미지

buffer 1와 2에 기록할 때에는
mutex를 걸어서 한 쪽이 쓰고 있으면 mutex에 기록하라는 이야기 같습니다.
맞는지요?

만약에 이렇게 한쪽에서 쓰고 있는 buffer에 기록하기 위해서 다른 Thread가
접근 했을 때.. 이 쓰레드는 이 때 무엇을 해야 하나요? mutex라 끝나기를
기다려야 할건데요.. 이 기다림이 얼마나 작을까요? 일단 이런 기다리는 시간을
최소화 할 수 있는 방법이 궁금합니다... 그리고 기다리다가 mutex를 놓아다는 것을 통지하는 적극적인 방법이 있나요? 그리고 참고로 buffer를 두개 둔 것은 파일 기록 시간이 얼마나 걸릴지 모르기 때문에 두개를 두었습니다.

낙엽의 이미지

윗분의 설명은 다음과 같습니다.

thread 1
    while
    {
        mutex_lock() --> 추가
        buffer1 기록
        or
        buffer2 기록
        mutex_unlock() --> 추가
    }
    
thread2
    while
    {
        mutex_lock() --> 추가
        file 쓰기  buffer1
        or
        file 쓰기  buffer2
        mutex_unlock() --> 추가
    }

tread_main
    thread1 생성
    thread2 생성
    
    while
    {
        buffer1 기록
        or
        buffer2 기록
    }
ssehoony의 이미지

일단 쓰레드간에 특정 상태 변화를 알리기 위해서
pthread_cond_wait (condition,mutex)
pthread_cond_signal (condition)
pthread_cond_broadcast (condition)
라는 식의 pthread_cond_xxxx 계열 함수를 사용하시면 되는데요.
사용방법은 알아서 연구해 보세요 ^^;;

로그의 시간이 뒤죽 박죽 되는 원인은 확실히 알고 계시는 상태인가요?
단순히 슬립을 줘서 해결하는 그런거 말고요.
구조상으로 제가 볼때는 버퍼에 기록하는 두 쓰레드의 실행 순서 문제인 것 같은데요. (넘 당연한 말을 하나? ^^;, 파일을 기록하는 쓰레드 말고 thread 1 하고 thread main 을 이야기 하는거져)
쓰레드 A : 시간 읽기 -> 쓰레드 B : 시간 읽기 -> 쓰레드 B : 버퍼 기록하기 -> 쓰레드 A : 버퍼 기록하기
이런식으로 순서가 뒤바뀌기 때문에 그런것 같은데요.

여기서 궁금한건 시간 읽기 -> 작업 -> 버퍼 기록 인지 아니면 작업 -> 시간 읽기 -> 버퍼 기록 인지 여부가 궁금하네요.

전자라면, LOCK -> 시간 읽기 -> 작업 -> 버퍼 기록 -> UNLOCK 으로 간다면 쓰레드를 사용하는 의미가 사라질거구요.

후자라면, 작업 -> LOCK -> 시간 읽기 -> 버퍼 기록 -> UNLOCK 라면 쓰레드를 사용해서 효과를 보는 구조일 것 같네요.

꼭 작업 전에 시간을 읽어야 한다면 로그에 시간이 섞이는건 쓰레드이기 때문에 당연한 결과이고 해결할 방법이 없습니다. (물론, 전자의 설명 처럼 lock 걸면 되지만 그렇게 하면 쓰레드를 사용하는거라고 말 할 수 없으니깐 그건 해결 방법이 아니겠죠 ^^)

혹시 뮤텍스가 lock 이 됐다가 unlock 된걸 다른 쓰레드에게 알리기 위해서
"기다리다가 mutex를 놓아다는 것을 통지하는 적극적인 방법이 있나요?" 이런 질문을 하셨다면 이건 신경 쓰실 필요 없습니다.
그건 pthread 라이브러리의 lock 함수에서 알아서 해주는 겁니다.
다시 말해, lock 함수를 호출했는데 이미 lock 걸려 있으면 sleep 했다가 unlock 될때까지 계속 기다렸다가 unlock 이 되면 그때서야 sleep 을 풀고 계속 진행합니다. 이런 기능때문에 데드락 (dead lock) 문제가 발생하긴 하지만요 ^^; (이 데드락은 cond 관련 함수를 이용해서 해결 할 수 있습니다.)

궁금하신 부분에 대해 잘 답변해 드린건지 모르겠네요.
혹시 부족하다면 좀 더 구체적으로 질문해 주시면 다시 답변해 드리겠습니다.

댓글 달기

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