thread 문제인거 같습니다 조언부탁드리겠습니다.

ecstasy5001의 이미지

2종류의 스레드가 있습니다.

thread_a 는 여러개가 될수 있고 thread_b 는 하나만 돌아갑니다.

프로그램이 잘돌아가다가 thread_a 가 1개 이상되면.. 랜덤한 시간에... 블럭이 걸립니다.

A스레드는 패킷의 정보를 읽어와서 메인에 전역으로 선언되어있는 자료구조체에 정보를 저장합니다.

B스레드는 5초마다 A스레드에서 생성한 정보를 읽어와서 서버로 전송을 합니다.

Thread_data_Mutex 는 전역으로 선언되어 있습니다

아래는 주요 부분의 코드입니다.

/////////////////thread a/////////////////////
void *thread_a(void *data)
{
while(loop)
{
LogFile("thread a enter loop");
pthread_mutex_lock(&Thread_data_Mutex);
LogFile("thread a enter mutex");

..
..
.. pcap으로 패킷을 캡쳐하고 패킷의 정보를 메인에서 선언한 전역 변수 구조체에 정보를 입력하는 과정

LogFile("thread a before exit mutex");
pthread_mutex_unlock(&Thread_data_Mutex);
LogToFile("thread a exit mutex");

} //while end

}

////////////////////thread b/////////////////////////
void *thread_b(void *data)
{
while(loop)
{
sleep(5);
LogFile("thread b enter");
pthread_mutex_lock(&Thread_data_Mutex);
LogFile("thread b mutex lock");
..
..
..
.. //thread a 에서 정보를 채워놓은 메인에 전역으로 선언되어있는 변수를 참조하여 데이터 가공후 서버로 전송
..
pthread_mutex_unlock(&Thread_data_Mutex);
LogFile("thread b mutex unlock");
sendtoserver(xxx) //서버로 데이터를 전송하는 함수
LogFile("thread b send data");

}
}

아래는 정상적으로 통신이 될때 로그 입니다.

thread a enter loop
thread a enter mutex
thread a before exit mutex
thread a exit mutex
위 네줄이 반복되다가 sleep 에서 thread_b가 깨어나면
thread b enter
thread b mutex lock
thread b mutex unlock
thread b send data
thread a enter loop
thread a enter mutex
thread a before exit mutex
thread a exit mutex
..............

블럭 걸릴때 로그 입니다.

위와 마찮가지로
thread a enter loop
thread a enter mutex
thread a before exit mutex
thread a exit mutex
네줄이 반복되다가 sleep 에서 thread_b가 깨어나면.

thread a enter loop
thread a enter mutex
thread b enter
..... .. ...... 이부분에서 더이상 응답이 없습니다.

제가 애초부터 설계를 잘못한 겁니까?

위에서도 말씀드렸지만 thread_a 는 몇개가 실행될 수도 있습니다. thread_b는 단 한개만 실행되고요..

thread_a 가 1개 실행되는 동안에는 문제가 발생하지 않는데 1개 이상이 되면 그때부터 저런 현상이 발생되네요..

조언 부탁드리겠습니다. ㅜㅜ

totohero의 이미지

thread_a든 thread_b든 (위의 로그상으로는 thread_a 인것 같지만) mutex를 lock한 상태에서 blocking된 것 같은데요. 패킷을 캡쳐하거나 서버로 전송하는 것이라 한다면 아마 blocking될 수 있는 system call을 사용하셨을 것으로 보입니다. mutex lock한 상태에서 blocking될 수 있는 system call을 쓰는 것은 일단 바람직하지 않다고 생각합니다. 저라면 global data를 local로 복사하고 기능을 아래처럼 나누겠습니다.

1. mutex lock된 상태에서 global 영역에 저장된 데이터를 local variable(thread마다 존재하는 별도의 stack 영역)으로 복사한다. (non-blocking 동작)
2. mutex lock 풀고 패킷 전송한다.

그리고 while (1) 후에 바로 mutex lock을 건다고 한다면, 불필요한 상황에서도 계속 mutex lock/unlock을 반복하게 되어 있지는 않나요? 만약 그렇다면 처리해야할 일이 생긴 경우에만 동작할 수 있도록 condition variable을 사용하는게 좋다고 봅니다.

댓글 달기

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