In nginx, the ngx_time_update function can be executed by multiple threads, but as long as one thread executes this function, other threads do not need to execute this function.
For this requirement, the implementation plan provided by nginx is quite interesting. The first two sentences of
ngx_time_update are as follows:
if (!ngx_trylock(&ngx_time_lock)) { return; } // do something... ngx_unlock(&ngx_time_lock);
ngx_trylock and ngx_unlock are both macro definitions, and the code is as follows:
#define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) #define ngx_unlock(lock) *(lock) = 0
#define ngx_atomic_cmp_set(lock, old, set) \ ((ngx_atomic_uint_t) InterlockedCompareExchange((long *) lock, set, old) \ == old)
ngx_atomic_uint_t is the type alias of unsigned int.
At this point, it can be seen that this synchronization solution is implemented using InterlockedCompareExchange.
First of all, the Interlocked series of functions can ensure the atomicity of operations.
Assume that the value of the ngx_time_lock variable is now 0, and two threads have to execute the InterlockedCompareExchange function. At this time, only one thread will execute first, which changes the value of ngx_time_lock to 1 and returns 0. Another thread compares the new ngx_time_lock value (that is, 1) with 0. At this time, no exchange will occur, and the original value 1 is returned, ensuring that this thread returns at the if judgment.
In addition, the type definition of ngx_atomic_t is: typedef volatile unsigned int ngx_atomic_t;
The above introduces the multi-threaded time update model in nginx, including aspects of it. I hope it will be helpful to friends who are interested in PHP tutorials.