file lock and thread sync operations (I)

第一点,多线程,每个线程都open flock write,不必explicitly sync threads(mutex、rdlock等),每个线程操作锁的顺序内部有序,并且,如果文件以append方式打开,文件写入不会混乱,如果以trunc方式打开,则文件内容可能混乱(write offset的原因,引起覆盖)。
第二点,flock,是进程层面的锁(第一点可印证),同时,这个锁与kernel维护的open file table关联。可联想下process table -- open file table -- vnode/inode table。
第三点,只主线程中open,然后把fd传给各子线程,各线程通过explicit thread sync来操作共享的fd。这个方法也可行。与flock相比,哪个更好,待确认。

第四点,flock vs. lockf vs. flockfile。


#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/file.h>


#ifndef MYNB
# ifdef LOCK_NB
#  undef LOCK_NB
# endif
#define LOCK_NB 0
#endif


#ifdef __cplusplus
extern "C" {
#endif


#if 0
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#endif

void *thr_fn(void *data)
{
    pthread_t tid = pthread_self();
    const char *fn = (const char *)data;
    int fd, len;
    char buf[32];

    fprintf(stderr, "in thr... %lu\n", tid);

    // fd = open(fn, O_RDWR | O_CREAT | O_APPEND, 0666);
    fd = open(fn, O_RDWR | O_CREAT, 0666);

    if (fd == -1) {
        char errbuf[64];
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "in thr %lu: %s\n", tid, errbuf);
        return (void *)-1;
    }

    fprintf(stderr, "in thr %lu fd: %d\n", tid, fd);

    if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
        char errbuf[64];
        close(fd);
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "in thr %lu: %s\n", tid, errbuf);
        return (void *)-1;
    } else {
        fprintf(stderr, "in thr %lu: flock OK\n", tid);
    }

    len = snprintf(buf, sizeof(buf), "%lu\n", tid);
    fprintf(stderr, "in thr %lu, to be written: %d\n", tid, len);

#if 0
    pthread_mutex_lock(&mutex);
#endif

    len = write(fd, buf, len);
#if 0
    fsync(fd);
#endif

#if 0
    pthread_mutex_unlock(&mutex);
#endif

    fprintf(stderr, "in thr %lu, written: %d\n", tid, len);

    if (flock(fd, LOCK_UN | LOCK_NB) == -1) {
        char errbuf[64];
        close(fd);
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "in thr %lu: %s\n", tid, errbuf);
        return (void *)-1;
    } else {
        fprintf(stderr, "in thr %lu: flock un\n", tid);
    }

    close(fd);

    fprintf(stderr, "leaving thr... %lu\n", tid);

    return (void *)0;
}

int main(void)
{
    const char *fn = "./foo.txt";
    pthread_t tid1, tid2, tid = pthread_self();
    int fd, len;
    char buf[32];

    pthread_create(&tid1, NULL, thr_fn, (void *)fn);

    fprintf(stderr, "main %lu\n", tid);

#if 0
    sleep(2);
#endif

    // fd = open(fn, O_RDWR | O_CREAT | O_APPEND, 0666);
    fd = open(fn, O_RDWR | O_CREAT, 0666);

    if (fd == -1) {
        char errbuf[64];
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "main: %s\n", errbuf);
    }

    fprintf(stderr, "main fd: %d\n", fd);

    if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
        char errbuf[64];
        close(fd);
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "main: %s\n", errbuf);
    } else {
        fprintf(stderr, "main: flock OK\n");
    }

#if 0
    sleep(2);
#endif

    pthread_create(&tid2, NULL, thr_fn, (void *)fn);

    len = snprintf(buf, sizeof(buf), "%lu\n", tid);
    fprintf(stderr, "main, to be written: %d\n", len);

#if 0
    pthread_mutex_lock(&mutex);
#endif

    len = write(fd, buf, len);
#if 0
    fsync(fd);
#endif

#if 0
    pthread_mutex_unlock(&mutex);
#endif

    fprintf(stderr, "main, written: %d\n", len);

    if (flock(fd, LOCK_UN | LOCK_NB) == -1) {
        char errbuf[64];
        close(fd);
        strerror_r(errno, errbuf, sizeof(errbuf));
        fprintf(stderr, "main: %s\n", errbuf);
    } else {
        fprintf(stderr, "main: flock un\n");
    }

    close(fd);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    fprintf(stderr, "leaving main...\n");
    return 0;
}


#ifdef __cplusplus
}
#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值