#include #include #include #include #include pthread_t th[5] = {0}; void flock_init (struct flock *f, short int type, off_t start, off_t len) { f->l_type = type; f->l_start = start; f->l_len = len; } int flock_range_in_steps (int fd, int is_set, short l_type, int start, int end, int step) { int ret = 0; int i = 0; struct flock f = {0,}; for (i = start; i+step < end; i += step) { flock_init (&f, l_type, i, step); ret = fcntl (fd, (is_set)? F_SETLKW:F_GETLK, &f); if (ret) { perror ("fcntl"); goto out; } } out: return ret; } void * random_locker (void *arg) { int fd = *(int *)arg; int i = 0; int is_set = 0; /* use thread id to choose GETLK or SETLK operation*/ is_set = pthread_self () % 2; (void)flock_range_in_steps (fd, is_set, F_WRLCK, 0, 400, 1); return NULL; } int main (int argc, char **argv) { int fd = -1; int ret = 1; int i = 0; char *fname = NULL; if (argc < 2) goto out; fname = argv[1]; fd = open (fname, O_RDWR); if (fd == -1) { perror ("open"); goto out; } ret = flock_range_in_steps (fd, 1, F_WRLCK, 0, 2000, 2); for (i = 0; i < 5; i++) { pthread_create (&th[i], NULL, random_locker, (void *) &fd); } ret = flock_range_in_steps (fd, 1, F_WRLCK, 0, 2000, 2); for (i = 0; i < 5; i++) { pthread_join (th[i], NULL); } out: if (fd != -1) close (fd); return ret; }