flock()的作用范围是什么?

3

我正在测试在另一个线程中锁定文件描述符是否会影响主线程。

#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
//#include <share.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>

void *print_message_function( void *ptr );

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

int main (int argc, char * const argv[]) {

    pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int  iret1, iret2;

    iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message1);

    if(iret2)
    {
        fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
        fflush(stdout);
        exit(EXIT_FAILURE);
    }

        printf("pthread_create() for thread 2 returns: %d\n",iret2);

    pthread_mutex_lock(&mut);
    sleep(1);

    std::cout<<"Enter any key:"<<std::endl;
    std::cin >> input;

    if (fd2 = open( "file1",    O_RDWR | O_CREAT | O_TRUNC, 0700 | 0x10) == -1)
    {
        perror("Cannot open file 2.\n"); 
        fflush(stdout);
    }
    else
    {
        printf("File was opened 2!!\n");
        fflush(stdout);
        if(flock(fd2, LOCK_NB | LOCK_EX)==0)
        {
            printf("THE FILE WAS LOCKED 2.\n");
        }
        else if(errno == EAGAIN)
        {
            printf("The file is locked 2. Resource temporarily unavailable.\n");
        }
    }

    pthread_mutex_unlock(&mut);

    close(fd2);
    std::cout<<"File closed."<<std::endl;
    std::cin >> input;
    return 0;
}


void *print_message_function( void *ptr )
{
    char *message;
    message = (char *) ptr;
    printf("%s \n", message); 
    fflush(stdout);

    int fd1;

    if ((fd1 = open( "file1",   O_RDWR | O_CREAT | O_TRUNC, 0700 | 0x10)) == -1)
    {
        perror("thread: Cannot open file 1.\n");
        fflush(stdout);
        //std::cin >> input;
    }
    else
    {
        printf("File was opened 1!!\n");
        fflush(stdout);


        if(flock(fd1, LOCK_NB | LOCK_EX)==0)
        {
            printf("THE FILE WAS LOCKED 1.\n");
        }
        else if(errno == EAGAIN)
        {
            printf("The file is locked 1. Resource temporarily unavailable.\n");
        }
    }

    pthread_mutex_lock(&mut);
    pthread_mutex_unlock(&mut);

    printf("End of thread.\n");
}

输出结果:
[Session started at 2014-11-26 17:46:16 +0000.]
pthread_create() for thread 2 returns: 0
Thread 1 
File was opened 1!!
THE FILE WAS LOCKED 1.
Enter any key:
1
File was opened 2!!
THE FILE WAS LOCKED 2.
File closed.
End of thread.

我不明白为什么在线程内使用flock()不能防止主线程使用flock()获得锁。
根据linux man手册:
由flock()创建的锁与打开的文件描述符相关联,这意味着重复的文件描述符(例如通过fork(2)或dup(2)创建的)引用相同的锁,并且可以使用任何这些描述符修改或释放此锁。此外,该锁是通过任何这些重复描述符上的显式LOCK_UN操作或关闭所有这样的描述符来释放的。

可能是重复的问题:多个线程能够同时获取flock - pilcrow
@pilcrow,不是重复的问题。在您引用的问题中,各个线程都使用相同的文件描述符(如果没有,则没有一个答案是令人满意的)。而在这种情况下,它们是在同一文件上打开单独的描述符。根据文档,对于在同一文件上打开的不同描述符上的flock()可能会相互阻塞。 - John Bollinger
1
“print_message_function()”在结束时锁定和解锁互斥锁,但不在互斥锁的作用域内执行任何工作,这有点奇怪。如果您至少在持有互斥锁时执行“flock()”,那么行为是否会有所不同(就像其他线程已经执行的那样)?注意:您需要将主线程的“sleep()”移出其临界区。 - John Bollinger
1个回答

5

笔误。这行代码错误地将fd2(顺便说一下,你在发布的代码中没有声明)设置为0,即stdin

if (fd2 = open( "file1",    O_RDWR | O_CREAT | O_TRUNC, 0700 | 0x10) == -1)

因此,fd1fd2几乎肯定是指不同的文件,而您的练习的重点已经丢失了。您想要表达的应该是:
if ((fd2 = open("file1", ...)) == -1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接