This snippet is designed to lock a shared memory file by flock()
for 10 seconds and then release the lock. I ran it on two terminals to test if the lock is effective.
void main(void) {
int fd = shm_open("test_shm", O_CREAT | O_RDWR | O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO);
if (fd == -1 && errno == EEXIST) {
fd = shm_open("/my_test_shm", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
}
char *p = mmap(NULL, 128, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (flock(fd, fLOCK_EX) == -1) {
printf("Failed to flock, err %sn", strerror(errno));
} else {
sleep(10);
close(fd);
for ( ; ; );
}
return;
}
Tests have shown that the file could not be released when the file descriptor was closed. Per flock(2)
, the lock should be released. Why?
Locks created by flock() are associated with an open file
description (see open(2)). This means that duplicate file
descriptors (created by, for example, fork(2) or dup(2)) refer to
the same lock, and this lock may be modified or released using
any of these file descriptors. Furthermore, the lock is released
either by an explicit LOCK_UN operation on any of these duplicate
file descriptors, or when all such file descriptors have been
closed.
Then I discovered that by invoking munmap()
before close()
, the lock could be released. The documentation for munmap()
states the following. So, does this mean that the issue is due to the reference count increased by mmap()
?
The mmap() function shall add an extra reference to the file associated with the file descriptor fildes which is not removed by a subsequent close() on that file descriptor. This reference shall be removed when there are no more mappings to the file.
Then, I conducted tests using open()
instead of shm_open()
, and the result was that the lock could be released even without invoking munmap()
. So, why is the behavior different between shared memory files and normal files?
apple is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.