데드락 처리 방법

bigbaby의 이미지

안녕하세요

메인 함수에서 400개 정도의 쓰레드를 생성하여 작업을 처리하고 있습니다

400개 쓰레드는 각 작업 완료 후 하나의 파일에 로깅을 하는데

이때, 락 획득 -> 파일 쓰기 -> 락 해제 순으로 처리합니다.

갑자기 메인 함수에서 A시그널을 받아 종료해야되는 상황이 발생했습니다.

미리 등록한 A시그널 핸들러 함수에서 로깅 파일을 닫기 위해

락 획득하려고 했으나 블럭되어 데드락에 빠지게되었습니다.

아마도 400개중 하나의 쓰레드가 락 획득하여 파일에 쓰고 해제 전에

시그널을 받아 죽은 것으로 생각이 되는데..자원을 해제하기 위해 락을 얻어야하는

메인에서는 어떻게 구현을 해야할지 난감하네요 ^^

답변 부탁드립니다.

jick의 이미지

(Embedded OS가 아닌 제대로 된 멀티태스킹/파일입출력을 지원하는 OS라는 가정 하에...)

프로세스가 죽으면 파일이 자동으로 닫힐 테니 메인에서 락을 얻을 필요가 없습니다. 정상적인 OS라면 프로세스가 죽는 순간 그 프로세스가 사용하던 자원은 모두 OS가 알아서 해제합니다. (뭐 shared memory같은 변태적인 예외케이스가 있긴 합니다만...)

* 비슷한 답변 kldp에 열댓번쯤 단 것 같은...;;;

pastime의 이미지

stdio의 buffered IO를 이용하는 경우라면 얘기가 달라집니다. 마찬가지로 커널이 알 수 없는 사용자 영역의 버퍼링이 이루어지고 있다면 이를 처리해야 겠지요..

logging을 위해 정말로 lock이 필요하다면 아래분의 답변처럼 lock을 잡고 있는 동안 signal을 block하는 것이 더 좋아보입니다.

익명 사용자의 이미지

man pthread_sigmask

unipro의 이미지

write 시스템 콜을 사용하시고, "락 획득 -> 파일 쓰기 -> 락 해제"를 제거하세요.
fprintf 류의 함수 대신에, sprintf 류 함수와 write 시스템 콜을 사용하세요.
제가 알기로는 write는 쓰레드에 안전합니다.

내 블로그: http://unipro.tistory.com

cinsk의 이미지

pthread를 쓴다면, 그리고, 모든 Logging이 한 함수 호출 (예: fprintf)로 이루어진다면, 따로 lock 걸 필요 없습니다.
POSIX 표준에서 거의 모든 stream operation은 atomic하게 이루어집니다. (putc_unlocked 등 _unlocked 출력 함수 제외)

만약 하나의 Log entry가 여러번 stream 함수 호출로 이루어져있다면, flockfile/funlockfile을 쓰면 됩니다.

경험상 log 목적으로 일일히 lock/unlock을 하는 것 보다, 한 번 stream function 호출로 출력하게 하고, 나머지는 C library가 알아서 하게 하는게 나을 것 같습니다.

bigbaby의 이미지

좋은 답변 감사드립니다.

역시 고수들이시네요 ^^

좋은하루 보내세요~~

bejoy4him의 이미지

전 로그를 남길 때, 뮤텍스lock을 걸어서 남기고 있습니다.

남기는 함수는 fprintf를 사용하구요, lock을 거는 이유는
다른 쓰레드에서 남기는 로그와 뒤섞이지 않게 하기위해서입니다.

다음처럼요..
로그1: AAAAAAAAAAAAAAAAAAAAAAAAAAA
로그2: BBBBBBBBBBBBBBBBBBBBBBBBBBB

실제로그:
AAAAAAAAAAAAAAABBBBBBBBBBBB.....

평소에는 문제가 없다가, 특정상황이 되면 위처럼 뒤죽박죽 되는 경우가 있어서 lock을 걸도록 수정하였습니다.
cinsk님 말씀처럼 로그 한줄을 남기기 위해서 여러번의 stream 함수 호출이 있었는지는 확인하지 못하였습니다.

질문입니다.
1. fprintf류의 함수를 사용할 경우, 따로 lock을 걸지 않아도 로그가 섞이는 일은 발생하지 않나요?
제가 맞게 이해했는지 한번더 확인 질문 드리는 것입니다.
물론 1라인을 출력하는데 fprintf함수가 1회만 호출된다는 전제하에서...

2. 1라인을 출력하는데 여러번의 stream함수 호출이 이뤄진다면 flockfile/funlockfile 함수를 사용하라고
권장하셨는데, flockfile/funlockfile함수가 뮤텍스 lock/unlock에 비해 이점이 있나요?

jeongheumjo의 이미지

저도 이 쓰레드에 관심이 많이 가네요..
같은 고민을 해본 적이 있거든요.
저도 결국 동기화를 하고 있는데 cinsk 님의 방법은 아주 좋아보입니다.
아마 cinsk 님의 방법은 깔끔한 출력이 보장되지는 못할 것 같습니다.
두 개 이상의 로그가 섞여서 나타나지 않을까 싶습니다.
깔끔한 출력을 원한다면 동기화를 해야 할 것 같구요..
결국 둘 간의 (속도및 안정성 우선, 보기 좋은 로깅 구현 우선) 트레이드오프로 결정해야할 듯... 싶고요.
그렇다면 로깅 함수에 해당 옵션을 줄 수 있도록 하면 좋지 않을까 ...
어디까지나 저의 짐작이구요.
저도 이 쓰레드의 진행상황이 무척 궁금합니다.

댓글 달기

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