file lock and thread sync operations (I)
2014-06-16 16:23
344 查看
第一点,多线程,每个线程都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
第二点,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
相关文章推荐
- The sandbox is not sync with the Podfile.lock问题解决方案
- Thread and Sync In C# (C#中的线程与同步)
- IOS 从网上下载的项目,运行时出现“The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update y”
- cadence Resolve lock file and re-run netrev 解决
- mac 项目the sandbox is not sync with the podfile.lock问题解决
- mongodb exception in initAndListen: 12596 old lock file, terminating解决方法
- The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods install
- IOS--The sandbox is not in sync with the Podfile.lock.
- iOS 'The sandbox is not sync with the Podfile.lock
- The pid file locates at /var/run/cloud-management.pid and lock file at /var/lock/subsys/cloud-management.
- exception in thread "main" brut.androlib.AndrdolibException: Counld not decode arse file
- 在GitHub上下载Demo 运行时候会出现The sandbox is not sync with the Podfile.lock
- JMeter学习-027-JMeter参数文件(脚本分发)路径问题:jmeter.threads.JMeterThread: Test failed! java.lang.IllegalArgumentException: File distributed.csv must exist and be readable解决方法
- MYSQL无法启动,出现CAN’T OPEN AND LOCK PRIVILEGE TABLES: INCORRECT FILE FORMAT ‘db’
- The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods install
- Thread and Sync In C# (C#中的线程与同步)
- iOS "The sandbox is not in sync with the Podfile.lock"解决方案
- iOS CocoaPods iOS 'The sandbox is not sync with the Podfile.lock'问题解决
- apktool反编译:Exception in thread "main" brut.androlib.AndrolibException: Could not decode arsc file
- exception in initAndListen: 12596 old lock file, terminating