Lock files against semaphores

Just out of curiosity, what is the preferred way to achieve interprocess synchronization on Linux? The sem*(2) family of system calls seems to have a very clumsy and outdated interface, while there are three ways to lock files - fcntl() , flock() and lockf() .

What are the internal differences (if any) and how will you justify using each of them?

+7
c linux unix interprocess
source share
4 answers

None. Actual versions of pthread_* (e.g. phtread_mutex_t ) allow you to place variables in shared segments created with shm_open . You just need to add an extra parameter to the init calls.

Do not use semaphores ( sem_t ) if you do not need it, they are too low and confused IO, etc.

Do not abuse file locking for interprocess management. This is not done for this. In particular, you have no way to clear file metadata, such as locks, so you never know when the lock / unlock will become visible to the second process.

+8
source share

You have many options from a rich history, as DarkDust noted. For what is worth my decision tree, something like this happens:

Use mutexes when only one process / thread can access at a time.

Use semaphores when two or more (but still finite) processes / threads can use a resource.

Use POSIX semaphores if you really don't need something that SYSV semaphores have - for example. UNDO, PID of the last operation, etc.

Use file locking in files or if it does not meet your requirements.

+4
source share

Different lock / semaphore implementations have come true in different systems. In System V Unix, you had semget / semop , POSIX defined a different implementation with sem_init , sem_wait and sem_post . And flock arose in 4.2BSD, as far as I could find out.

Because they all have gained some relevance, Linux now supports them all to make porting easier. In addition, flock is a mutex (locked or unlocked), but the sem* functions (both SysV and POSIX) are semaphores: they allow the application to provide several simultaneous access processes, for example. you can allow access to the resource for 4 processes simultaneously with semaphores. You can implement a mutex with semaphores, but not vice versa. I remember that in Mark J. Rochind's excellent UNIX Advanced Programming, he demonstrated how to transfer data between processes through semaphores (very inefficient, he did this only to prove that it can be done). But I could not find anything reliable regarding efficiency.

I think it is more like "Use what you want."

+2
source share

A potentially significant difference may be the fairness of the distribution of resources. I don’t know the details about the implementation of the semget/semop , but I suspect that it is usually implemented as a “traditional” semaphore while planning is in progress. As a rule, I believe that released streams are processed based on FIFO (first semaphore is expected first). I do not think this will happen with file locking, as I suspect (again, just guessing) that the processing is not performed at the kernel level.

I had existing code for checking semaphores for IPC purposes, so I compared two situations (one of which uses semop and one that uses lockf ). I did a bad test and just ran to application instances. A common semaphore was used to synchronize the start. When the semop test was run, both processes completed 3 million cycles almost in sync. On the other hand, the lockf loop was not so fair. One process usually ends, while the other has completed only half the cycle.

The semop test loop looked like this. The semwait and semsignal are just wrappers for semop calls.

  ct = myclock(); for ( i = 0; i < loops; i++ ) { ret = semwait( "test", semid, 0 ); if ( ret < 0 ) { perror( "semwait" ); break; } if (( i & 0x7f ) == 0x7f ) printf( "\r%d%%", (int)(i * 100.0 / loops )); ret = semsignal( semid, 0 ); if ( ret < 0 ) { perror( "semsignal" ); break; } } printf( "\nsemop time: %d ms\n", myclock() - ct ); 

The overall runtime for both methods was approximately the same, although the lockf version was actually faster overall due to scheduling injustice. As soon as the first process is completed, the other process will have undeniable access for approximately 1.5 million iterations and will work very quickly.

When running uncontested (one process of getting and releasing locks), the semop version was faster. It took about 2 seconds for 1 million iterations, while the lockf version took about 3 seconds.

This was done in the following version:

 []$ uname -r 2.6.11-1.1369_FC4smp 
+2
source share

All Articles