Python class library 32 [multi-thread synchronization lock + rlock + semaphore + event]

Source: Internet
Author: User

 

Multithreading basics: Python class library 32 [multi-thread synchronization]

 

One-Thread Synchronization

Because the python interpreter of cpython is executed in single-threaded mode, many threads of Python cannot fully utilize the resources of multi-core CPUs. Multi-process is recommended in most cases.

The synchronization of multiple threads in python is basically the same as that in other languages, mainly including:

Lock & rlock: Used to ensure multi-threaded Multi-shared resource access.

Semaphore: used to ensure the upper limit of multi-thread access to certain resources, such as resource pools.

Event: the simplest way to communicate between threads. One thread can send signals, and other threads can perform operations after receiving signals.

 

Example 2

1) Lock & rlock

The status of the lock object can be locked or unlocked,
Use acquire () to set the status to locked;
Use release () to set the status to unlocked.

If the current status is unlocked, acquire () changes the status to locked and returns immediately. When the status is locked, acquire () will be blocked until another thread calls release () to change the status to unlocked, and then acquire () can set the status to locked again.

Lock. Acquire (blocking = true, timeout =-1). The blocking parameter indicates whether to block the waiting time of the current thread, and the timeout parameter indicates the waiting time during blocking. If the lock is obtained successfully, the acquire () function returns true; otherwise, false is returned. If the lock is not obtained during timeout, false is returned.

 

Instance: (ensure that only one thread can access Shared Resources)

Import Threading
Import Time

Num = 0
Lock = threading. Lock ()

Def Func (ST ):
Global Num
Print (Threading. currentthread (). getname () + ' Try to acquire the lock ' )
If Lock. Acquire ():
Print (Threading. currentthread (). getname () + ' Acquire the lock. ' )
Print (Threading. currentthread (). getname () + " : % S " % STR (Num ))
Num + = 1
Time. Sleep (ST)
Print (Threading. currentthread (). getname () + ' Release the lock. ' )
Lock. Release ()

T1 = threading. Thread (target = func, argS = (8 ,))
T2 = threading. Thread (target = func, argS = (4 ,))
T3 = threading. Thread (target = func, argS = (2 ,))
T1.start ()
T2.start ()
T3.start ()

 

 

Result:

The difference between rlock and lock is that in addition to the locked and unlocked statuses, rlock also records the owner and number of recursive layers of the current lock, so that rlock can be acquire () multiple times by the same thread ().

 

2) semaphore

Semaphore manages a built-in counter. Each time acquire () is called, the built-in counter-1; when release () is called, the built-in counter + 1;

The counter cannot be smaller than 0. When the counter is 0, acquire () will block the thread until other threads call release ().

 

Instance: (only two threads can obtain semaphore at the same time, that is, the maximum number of connections can be limited to 2 ):

Import Threading
Import Time

Semaphore = threading. semaphore (2)

Def Func ():
If Semaphore. Acquire ():
For I In Range (5 ):
Print (Threading. currentthread (). getname () + ' Get semaphore ' )
Semaphore. Release ()
Print (Threading. currentthread (). getname () + ' Release semaphore ' )


For I In Range (4 ):
T1 = threading. Thread (target = func)
T1.start ()

 

 

Result:

 

 

3) event

The event contains a flag, which is false at the beginning.
You can use set () to set it to true;
Or use clear () to reset it to false;
You can use is_set () to check the flag status;
The other most important function is wait (timeout = none), which is used to block the current thread until the internal flag of the event is set to true or timeout. If the internal flag is true, the wait () function is returned.

 

Instance: (threads communicate with each other)

Import Logging
Import Threading
Import Time

Logging. basicconfig (Level = logging. debug,
Format ="(% (Threadname)-10 s: % (Message) S",
)

Def Wait_for_event_timeout (E, T ):
""" Wait t seconds and then timeout """
While Not E. isset ():
Logging. debug ( " Wait_for_event_timeout starting " )
Event_is_set = E. Wait (t)
Logging. debug ( " Event Set: % s " % Event_is_set)
If Event_is_set:
Logging. debug ( " Processing Event " )
Else :
Logging. debug ( " Doing other work " )

E = threading. Event ()
T2 = threading. Thread (name = " Nonblock " ,
Target = wait_for_event_timeout, argS = (E, 2 ))
T2.start ()
Logging. debug ( " Waiting before calling event. Set () " )
Time. Sleep (7)
E. Set ()
Logging. debug ( " Event is set " )

 

Running result:

 

III others

1) thread local variables

The value of a local variable in a thread is related to the thread. The difference is different from that of a global variable. The usage is very simple as follows: mydata = threading. Local () mydata. x = 1

 

2) use the With keyword for lock, semaphore, and condition to call acquire () and release () manually ().

 

Complete!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.