A potentially significant difference might be the fairness of the resource distribution. I don't know the details of the implementation of the semget/semop
family, but I suspect that it is typically implemented as a "traditional" semaphore as far as scheduling goes. Generally, I believe the released threads are handled on a FIFO basis (first one waiting for the semaphore is released first). I don't think this would happen with file locking since I suspect (again just guessing) that the handling is not performed at the kernel level.
I had existing code sitting around to test semaphores for IPC purposes, and so I compared the two situations (one using semop
and one using lockf
). I did a poor man's test and just ran to instances of the application. The shared semaphore was used to sync the start. When running the semop test, both processes finished 3 million loops almost in sync. The lockf loop, on the other hand, was not nearly as fair. One process would typically finish while the other one had only completed half the loops.
The loop for the semop test looked like the following. The semwait
and semsignal
functions are just wrappers for the 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 total run time for both methods was about the same, although the lockf version actually was faster overall sometimes because of the unfairness of the scheduling. Once the first process finished, the other process would have uncontested access for about 1.5 million iterations and run extremely fast.
When running uncontested (single process obtaining and releasing the 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 run on the following version:
[]$ uname -r
2.6.11-1.1369_FC4smp