First, what is sequential lock
an optimization of sequential locks on read and write locks , when using sequential locks, reads are not blocked by the Write execution unit ( in a read-write lock, the write operation must wait for all read operations to complete ). That is, when writing to a critical resource, it is also possible to read from this critical resource, which reads and writes at the same time, but does not allow simultaneous writing of the data . If the read execution unit has already written to the write execution unit during the read operation, then the read execution unit must be restarted, which guarantees the integrity of the data, which may be minimal. Sequential lock performance is very good, while he allows read and write at the same time, greatly improving the concurrency.
Second, the defect of sequential lock
The drawback of sequential locks is that mutually exclusive access to a resource cannot be a pointer , because a write operation can cause the pointer to fail, and an unexpected error occurs when the read operation operates on a failed pointer.
Sequential locks are more efficient in some situations than read-write locks, but read-write locks can be applied to all occasions, and sequential locks do not, so sequential locks do not completely replace read-write locks .
Third, the realization of sequential lock
In the Linux kernel, there are sequential lock implementations:
typedefstruct{unsigned sequence; /*Sequential Counter*/spinlock_tLock;} seqlock_t;StaticInlinevoidWrite_seqlock (seqlock_t *SL) {Spin_lock (&sl->Lock); ++sl->sequence; SMP_WMB ();}StaticInlinevoidWrite_sequnlock (seqlock_t *SL) {SMP_WMB (); SL->sequence++; Spin_unlock (&sl->Lock);}Static__always_inline unsigned read_seqbegin (Constseqlock_t *SL) {unsigned Ret;repeat:ret= Access_once (sl->sequence); if(Unlikely (Ret &1) ) {Cpu_relax (); Gotorepeat; } SMP_RMB (); returnret;} /** Test If reader processed invalid data. * * If Sequence value changed then writer changed data "in" section. */Static__always_inlineintRead_seqretry (Constseqlock_t *SL, unsigned start) {SMP_RMB (); returnUnlikely (sl->sequence! =start);}
View Code
iv. use of sequential locks
The write operation unit of the sequential lock executes the following code:
Write_seqlock (&seqlock); write_something (); // write operation code block Write_sequnlock (&seqlock);
The read operation unit of the sequential lock executes the following code:
Do { = Read_seqbegin (&seqlock); // read_something (); // while// Call this function at the end of the read to check if there is a write execution unit that operates on the resource and reread if any.
v. A way of implementation under the Windows platform
Refer to the "Multi-threaded thing (Order Lock)" article content, organized a Windows platform under the implementation of a sequential lock. The code is as follows:
typedefstruct_sequence_lock{unsignedintsequence; HANDLE Hlock;} sequence_lock;unsignedintGet_lock_begin (sequence_lock*Hseqlock) {Assert (NULL!=Hseqlock); returnHseqlock->sequence; } intGet_lock_retry (sequence_lock* hseqlock, unsignedintvalue) {unsignedintNew_value; ASSERT (NULL!=Hseqlock); New_value= hseqlock->sequence; return(New_value &0x1) || (new_value ^value); }voidGet_write_lock (sequence_lock*Hseqlock) {Assert (NULL!=Hseqlock); WaitForSingleObject (Hseqlock-Hlock); Hseqlock->sequence + +;} voidRelease_write_lock (sequence_lock*Hseqlock) {Assert (NULL!=Hseqlock); Hseqlock->sequence + +; ReleaseMutex (Hseqlock-hlock);}
View Code
Use the same time method, refer to the following code:
voidRead_process (sequence_lock*Hseqlock) {unsignedintsequence; Do{sequence=Get_lock_begin (Hseqlock); /*Read Operation*/ } while(Get_lock_retry (hseqlock, Sequence));}voidWrite_process (sequencce_lock*Hseqlock) {Get_write_lock (Hseqlock); /*Write Operation*/Release_write_lock (Hseqlock);}
View Code
As you can see, the sequential lock principle and usage are the same.
Summary:
- There are two situations in which a read lock exits: A write operation is in progress or there is no write lock
- Mutually exclusive actions are required between write locks
- The resource for a mutex operation cannot be a pointer , otherwise it may cause an exception when accessed because it is possible to write while reading
- Sequential locks do not replace read-write locks, because read-write locks guarantee all data operations, and sequential locks are not
Sequential lock of multithreaded programming