Skip to content

Instantly share code, notes, and snippets.

@shnya
Created January 2, 2011 17:54
Show Gist options
  • Save shnya/762686 to your computer and use it in GitHub Desktop.
Save shnya/762686 to your computer and use it in GitHub Desktop.
multithread file locking test based on http://kzk9.net/blog/2007/05/flock2.html
#include <sys/file.h>
#include <pthread.h>
#include <assert.h>
#include <semaphore.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
static int locked = 0;
static pthread_mutex_t locked_mutex = PTHREAD_MUTEX_INITIALIZER;
int lock_flock(int fd){
return flock(fd, LOCK_EX);
}
int unlock_flock(int fd){
return flock(fd, LOCK_UN);
}
int lock_fcntl(int fd){
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
int res = fcntl(fd, F_SETLKW, &lock);
return res;
}
int unlock_fcntl(int fd){
struct flock lock;
int res;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if(fcntl(fd, F_GETLK, &lock) < 0){
// LOCK情報取得失敗
return -1;
}else if(lock.l_type == F_UNLCK){
// 既にLOCKされていなかった
return 0;
}
lock.l_type = F_UNLCK;
res = fcntl(fd, F_SETLKW, &lock);
return res;
}
void*
func1(void* arg)
{
int r;
char ch = ((char *)arg)[0];
while (1) {
FILE *f = fopen("test.txt", "a+");
assert(f != NULL);
int fd = fileno(f);
assert(f >= 0);
r = lock_fcntl(fd);
assert(r == 0);
pthread_mutex_lock(&locked_mutex);
assert(locked == 0);
locked = 1;
pthread_mutex_unlock(&locked_mutex);
fwrite(&ch, 1, 1, f);
fwrite(&ch, 1, 1, f);
printf("%ld\n", pthread_self());
pthread_mutex_lock(&locked_mutex);
locked = 0;
pthread_mutex_unlock(&locked_mutex);
sched_yield();
r = unlock_fcntl(fd);
assert(r == 0);
fflush(f);
fclose(f);
}
return NULL;
}
#define THREAD_NUM 200
int
main(void)
{
pthread_t ths[THREAD_NUM];
int i;
for (i = 0; i < THREAD_NUM; i++) {
char ch[1];
ch[0] = 'a' + i;
pthread_create(&ths[i], NULL, func1, (void*)ch);
}
for (i = 0; i < THREAD_NUM; i++)
pthread_join(ths[i], NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment