After searching on the Internet, there are two methods, but neither of them are very good: one is to simply use process ID + timestamp, or process ID + random number to generate an approximate unique ID. Although it is simple, I am not willing to pursue "perfection". This makes sense, and the process will last for a long time in Apache2 and later, and the probability of collision of the generated ID is still relatively high; the second idea is to use Mysql's auto-increment field, which cannot be considered, not to mention the low efficiency. There is no database at all in my design.
Obtaining incremental IDs is a process:
1. Read the ID from a global storage
2. Add 1 to the ID
3. Store the ID back into the global storage
in multiple The above three steps need to be used as single-step atomic operations in the process or thread program to ensure the uniqueness of the ID.
It is easy to solve in Java. This is because most Java programs run in a multi-threaded manner. Each thread can share variables in the Java process, and can easily add thread locks to control the synchronization of thread operations. In PHP, there is no problem in storing the ID globally. It can be placed in the session, or at worst in a file, but inter-process synchronization is a problem.
In fact, process scheduling and management are functions that the operating system kernel must implement. The semaphore (also called a semaphore) introduced today is a technology that solves process synchronization on Unix/Linux.
Signal lights were originally used as a management mechanism on railways. Most of the railways we see today are two-track, but some sections are affected by mountains and terrain and only have a single track. It must be ensured that only one train can run at the same time. through these sections. In the early days, railways were managed by signal lights: when no train passed by, the signals were idle. Once a train entered this section, the signal lights became in use. When other trains passed by, they needed to wait for the previous train to leave. Only when the exit signal becomes idle can you enter this section. Once another train enters, the signal light becomes busy again... to ensure the safe and smooth operation of the railway.
The Unix system manages and controls the status of the semaphore just like the railway administration controls the semaphore. Therefore, it can also be said that the semaphore is managed by the kernel. The semaphore can not only control the synchronization between processes, but also the synchronization between threads. .
Semaphores belong to system inter-process communication technology (IPC). Today we will only introduce the use of semaphores from the perspective of PHP. For technical details about IPC, please refer to Stevens's authoritative book "UNIX Network Programming Volume 2 Inter-Process Communication".
Look at the final code first:
Copy the code The code is as follows:
// -------------------------------------------------- -
// Increment the serial number ID (1~1000000000)
//
// The ID is stored in shared memory and synchronized through semaphore
// --- ---------------------------------------------
$IPC_KEY = 0x1234; //System V IPC KEY
$SEQ_KEY = "SEQ"; //KEY that stores the serial number ID in shared memory
//Create or get an existing one with "1234" Semaphore for KEY
$sem_id = sem_get($IPC_KEY);
//Create or associate an existing shared memory with "1234" as KEY
$shm_id = shm_attach($IPC_KEY, 64);
//Occupy the semaphore, which is equivalent to locking. Only one process can run this code at the same time
sem_acquire($sem_id);
//Get the serial number ID from the shared memory
$id = @shm_get_var($shm_id, $SEQ_KEY);
if ($id == NULL || $id >= 1000000000)
{
$id = 1;
}
else
{
$id++;
}
//Write the ID after "++" into the shared memory
shm_put_var($shm_id, $SEQ_KEY, $id);
//Release the semaphore, equivalent to unlocking
sem_release($sem_id);
//Close the shared memory association
shm_detach($shm_id);
echo "Serial ID: {$ id}";
?>
Line 009 defines a hexadecimal integer KEY. In PHP, only the IPC mechanism of System V is supported. A KEY needs to be associated with a specified resource (message queue, semaphore, shared memory).
Line 010 defines a KEY that stores incremental IDs in shared memory. This is PHP's idle use of System V shared memory: variables need to be stored in a KEY-VALUE method similar to hashtable. In the above code, shared memory is used as the storage container for the ID. It can also be replaced by other mechanisms such as Session and files. The focus of this article is on semaphores. The knowledge about shared memory will be discussed later (don’t forget the book recommended earlier) .
Line 013, obtain the semaphore with 1234 as the key in the system, and create one if it does not exist in the system.
Line 015, similar to line 13, obtains the shared memory with 1234 as the key in the system. If there is no shared memory in the system, create one. The second parameter 64 means to create a shared memory of 64bytes size.
Lines 018~034, synchronization code area, when a process or thread executes the sem_acquire function to occupy the semaphore, and during the process of calling the sem_release function to release the semaphore, other processes or threads will block when executing sem_acquire. Line 021 obtains the ID from the shared memory. The function shm_get_var is prefixed with "@" to shield the error message (when executed for the first time, there is no data with "SEQ" as the KEY in the shared memory, and a warning message will be printed on the page).
Other sentences are very simple and don’t need to be explained.
After the program is compiled, accessing this PHP page will output numbers incrementally.
We can view the semaphore and shared memory created in the program through the system command ipcs:
$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00001234 1212443 www-data 666 64 0
------ Semaphore Arrays --------
key semid owner perms nsems
0x00001234 163841 www- data 666 3
------ Message Queues --------
key msqid owner perms used-bytes messages
The first two paragraphs are shared memory and semaphores respectively, 0x00001234 is our Created KEY.
You can also delete it through the command ipcrm:
$ ipcrm -M 0x00001234 #Delete shared memory
$ ipcrm -S 0x00001234 #Delete semaphore
------------- --------------------------------
There is very little information about IPC in the PHP manual, which is not difficult at all. Imagine that what Stevens already explained thoroughly more than ten years ago is just packaged in PHP. How much more in-depth explanation is needed?
The text only talks about the use of semaphores through IDs. If you have a simpler way to generate auto-incrementing IDs, please let me know.
Some friends may also want to know the execution efficiency of semaphores. I will summarize it with an outdated buzzword: It is quite fast.
http://www.bkjia.com/PHPjc/320685.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/320685.htmlTechArticle I searched online and found two methods but neither are very good: one is to simply use process ID + time Stamp, or process ID + random number to generate an approximate unique ID, although simple but for those who pursue "perfection"...