Change language

Python | How to block critical sections

|

Code # 1:

import threading

 

class counter_share:

"" "

multiple streams can share.

"" "

  def __ init __ ( self , initial_key = 0 ):

self ._ key < code class = "keyword"> = initial_key

self ._ key_lock = threading.Lock ()

 

def incr ( self , delta = 1 ):

with self ._ key_lock:

# Increase counter with padlock

self ._ key + =   delta

 

def decr ( self , delta = 1 ):

with self ._ key_lock:

# Decrease the counter with a lock

self ._ key - = delta

Using the with statement in conjunction with blocking provides mutual exclusion. The exception is that only one thread (with the with statement) is allowed to execute a statement block at a time. 
A pending statement lock is obtained and released when control flow exits the block indented. Thread scheduling is inherently non-deterministic. This can lead to accidentally corrupted data and a "race condition" because locks cannot be used. Therefore, when multiple threads are accessing a shared mutable state, you should always use locks to avoid this.

In older Python code, there are often locks that are explicitly acquired and released.

Code # 2: Code Option 1

import threading

 

class counter_share:

# multiple threads can share counter objects

def __ init __ ( self , initial_key = 0 ):

  self ._key = initial_key

self ._ key_lock = threading.Lock ()

 

def incr ( self , delta = 1 ):

# Increase counter with padlock

self ._ key_lock.acquire ()

  s elf ._ key + = delta

  self . _key_lock.release ()

 

def decr ( self , delta = 1 ):

# Decrease the counter with a padlock

self ._ key_lock.acquire ()

  self ._ key - = d elta

self ._ key_lock.release ()

  • In situations where the release () is not called or an exception is not thrown when a lock is held, the with statement is much less error prone.
  • Each thread in a program is not allowed to acquire one lock at a time , this can potentially avoid deadlocks. Implement more advanced deadlock avoidance if this is not possible.
  • Synchronization primitives such as RLock and Semaphore objects are in the thread library.

In addition to just blocking a module, some other special tasks are solved:

  • RLock or a re-lockable lock object — it is a lock that can be acquired multiple times by the same thread.
  • It implements the code primarily through a locking or synchronization construct known as a "monitor". Only one thread can use the entire function or methods of the class while the lock is held, with this type of lock.

Code # 3: Implementing the SharedCounter class.

import threading

  

class counter_share:

# multiple threads can share counter objects

  _ lock = threading.RLock ()

 

def __init __ ( self , initial_key = 0 ):

self ._ key = initial_key

 

def incr ( self , delta = 1 ):

# Increase counter with padlock

with SharedCounter._lock:

self ._ key + =   delta

 

def decr ( self , delta = 1 ):

# Decrease the counter with a padlock

with SharedCounter._lock:

self . incr ( - delta)

  • Locking is meant to synchronize class methods, even though the lock is associated with mutable state each instance.
  • This version of the code has only one class-level lock shared by for all instances of a class.
  • Only one thread can use class methods at a time.
  • methods can call other methods that also use blocking if they already have locks. (For example, the decr () method).
  • If there are a large number of counters, this is much more memory efficient. However, this can lead to more lock conflicts in programs that use a large number of threads and frequently update the counter.

Semaphore element — this is a coarse synchronization dependent on a mutual counter. The counter increases when finished with a square. If the probability that the counter is zero, progress will be hindered until the counter is incremented by one more line. If the probability that the counter is nonzero, the explanation decreases the number and the line can continue. 
Instead of just blocking, semaphore elements are becoming more and more valuable to applications, including moving between lines or throttling. Although a semaphore can be used in a manner similar to a standard lock, the added versatility of use negatively affects execution.

Code # 4: Use a semaphore to limit the amount of parallelism in a piece of code.

from threading import Semaphore

import urllib.request

 
# maximum five threads can run concurrently

_ fetch_url_sema = Semaphore ( 5 )

 

 def fetch_url (url):

with _fetch_url_sema:

return urllib. request.urlopen (url)

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

Common xlabel/ylabel for matplotlib subplots

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

12 answers

NUMPYNUMPY

Flake8: Ignore specific warning for entire file

12 answers

NUMPYNUMPY

glob exclude pattern

12 answers

NUMPYNUMPY

How to avoid HTTP error 429 (Too Many Requests) python

12 answers

NUMPYNUMPY

Python CSV error: line contains NULL byte

12 answers

NUMPYNUMPY

csv.Error: iterator should return strings, not bytes

12 answers

News


Wiki

Python | How to copy data from one Excel sheet to another

Common xlabel/ylabel for matplotlib subplots

Check if one list is a subset of another in Python

sin

How to specify multiple return types using type-hints

exp

Printing words vertically in Python

exp

Python Extract words from a given string

Cyclic redundancy check in Python

Finding mean, median, mode in Python without libraries

cos

Python add suffix / add prefix to strings in a list

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

Python - Move item to the end of the list

Python - Print list vertically