쓰레드 간에 파일락하기

snoopy의 이미지

fcntl을 이용하여 파일에 대한 shared, exclusive 락을 걸 수 있다고

알고 있습니다.

그런데 이경우 프로세스간의 락만 가능하다고 알고 있습니다.

똑같은 기능으로 쓰레드간의 락을 걸수 있는 방법이 있을까요?

답변 부탁 드립니다.

vness의 이미지

flockfile, funlockfile 을 사용해보세요.

snoopy의 이미지

! 답변 고맙습니다 !

snoopy의 이미지

안녕하세요
flockfile, funlockfile의 사용법에 대해 질문드립니다

vness님의 답변 덕분에 thread상에서 file락을 하는 함수가 flockfile, funlockfile이라는 걸 알게 되었는데 사용법을 잘 모르겠습니다.
테스트를 위해 아래와 같이 사용해 보았습니다.

char *lockfile = "lockfile" ;

int main() {

        FILE *fp ;
        fp = fopen(lockfile, "w") ;
        if(fp == NULL) {
                perror("fopen error: ") ;
                return 1 ;
        }
        flockfile(fp) ;
        cout << "lock in main" << endl ;

        pthread_t thread ;
        if(pthread_create(&thread, NULL, threadFunc, NULL) < 0) {
                perror("thread error: ") ;
                return 1 ;
        }
        sleep(4) ;

        funlockfile(fp) ;
        cout << "unlock in main" << endl ;
        fclose(fp) ;

        pthread_join(thread, NULL) ;

        return 0 ;
}

void *threadFunc(void *arg) {

        FILE *fp ;
        fp = fopen(lockfile, "w") ;
        if(fp == NULL) {
                perror("fopen error: ") ;
                return NULL ;
        }
        flockfile(fp) ;
        cout << "lock in thread" << endl ;

        sleep(3) ;

        funlockfile(fp) ;
        cout << "unlock in thread" << endl ;
        fclose(fp) ;

        return NULL ;
}

main과 쓰레드에서 각각
fopen, flockfile, funlockfile, fclose 순서대로 호출을 하였습니다.
제 예상대로라면

lock in main
unlock in main
lock in thread
unlock in thread

이런식으로 나와야하는데 실행결과는

lock in main
lock in thread
unlock in thread
unlock in main

이런 식으로 나왔습니다.
즉 락이 제대로 안되었다는 건데
어느 부분이 잘못되었는지 모르겠습니다T-T.
답변 부탁드립니다!

김충길의 이미지

스레드 함수내에서 fopen의 두번째 파라메터가 r+ 가 되어야 할거 같은데요.
아니면 main 함수의 fp를 그대로 사용해야 하는건 아닌지.

screen + vim + ctags 좋아요~

ssehoony의 이미지

쓰레드간이면 뮤텍스를 이용해도 되겠군요
파일락을 사용하면 시스템콜이 되서 포펀먼스 상에서도 손실이 좀 크겠지만
뮤텍스를 이용하면 손실도 적을테니 파일락보다 뮤텍스가 좋지 않을까 하네요.

snoopy의 이미지

김충길 wrote:
아니면 main 함수의 fp를 그대로 사용해야 하는건 아닌지.

답변주신대로 FILE * 포인터를 전역변수로 선언하여 아래와 같이 코드를 짜서 해보니 라킹이 잘 되었습니다
감사합니다^^

char *lockfile = "lockfile" ;
FILE *fp ;

int main() {

        fp = fopen(lockfile, "w") ;
        if(fp == NULL) {
                perror("fopen error: ") ;
                return 1 ;
        }
        flockfile(fp) ;
        cout << "lock in main" << endl ;

        pthread_t thread ;
        if(pthread_create(&thread, NULL, threadFunc, NULL) < 0) {
                perror("thread error: ") ;
                return 1 ;
        }
        sleep(4) ;

        funlockfile(fp) ;
        cout << "unlock in main" << endl ;

        pthread_join(thread, NULL) ;
        fclose(fp) ;

        return 0 ;
}

void *threadFunc(void *arg) {

        flockfile(fp) ;
        cout << "lock in thread" << endl ;

        sleep(3) ;

        funlockfile(fp) ;
        cout << "unlock in thread" << endl ;

        return NULL ;
}

실행결과가 다음과 같이...

lock in main
unlock in main
lock in thread
unlock in thread

으흑...근데 제가 첨에 원한건 shared, exclusive 락에 대한 것이었는데
효율성을 생각한다면 뮤텍스를 사용한여 shared, exclusive 락을
구현하는것도 좋은 방법이겠네요 :o
답변 감사드립니다!

devilhero wrote:
쓰레드간이면 뮤텍스를 이용해도 되겠군요
파일락을 사용하면 시스템콜이 되서 포펀먼스 상에서도 손실이 좀 크겠지만
뮤텍스를 이용하면 손실도 적을테니 파일락보다 뮤텍스가 좋지 않을까 하네요.

댓글 달기

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