Python multi-threaded usage Example detailed

Source: Internet
Author: User
This paper analyzes the usage of Python multithreading. Share to everyone for your reference. Specific as follows:

Today, when learning how to learn Python multi-threading, I suddenly found that I was not very clear about the use of super, so first summarize some of the problems encountered. When I try to write the following code:

The code is as follows:

Class A ():
def __init__ (self):
Print "A"
Class B (A):
def __init__ (self):
Super (B, self). __init__ ()
# a.__init__ (self)
Print "B"
b = B ()


Appear:

The code is as follows:

Class A (object):
def __init__ (self):
Print "A"
Class B (A):
def __init__ (self):
Super (B, self). __init__ ()
# a.__init__ (self) # #这条语句是旧式的, there are potential problems and you should avoid using
Print "B"
b = B ()

(2)

The code is as follows:

__metaclass__=type
Class A ():
def __init__ (self):
Print "A"
Class B (A):
def __init__ (self):
Super (B, self). __init__ ()
# a.__init__ (self) # #这条语句是旧式的, there are potential problems and you should avoid using
Print "B"
b = B ()


Note: If at super (B, self). __init__ ()

Statement to add self, which is super (B, self), the following error occurs: __init__

The code is as follows:

Import threading, Time
Class MyThread (threading. Thread):
def __init__ (self, threadname = ""):
#threading. Thread.__init__ (self, name = ThreadName)
Super (MyThread, self). __init__ (name = ThreadName)
def run (self):
Print "starting====", Self.name, Time.ctime ()
Time.sleep (5)
Print "end====", Self.name, Time.ctime (),

m = MyThread ("M")
n = myThread ("n")

M.start ()
N.start ()


Results of the output:

starting==== m Mon 08 21:55:41 2011

starting==== n Mon 08 21:55:41 2011

If the main thread of a process finishes running and the child threads are still executing, the process will not exit until all the child threads have finished. For example, the following:

The code is as follows:

Import threading, Time
Class MyThread (threading. Thread):
def __init__ (self, threadname = ""):
#threading. Thread.__init__ (self, name = ThreadName)
Super (MyThread, self). __init__ (name = ThreadName)
def run (self):
Print "starting====", Self.name, Time.ctime ()
Time.sleep (5)
Print "end====", Self.name, Time.ctime (),

m = MyThread ("M")
M.start ()
Print "Main End"
Print


The result of the output is:

starting==== m Mon 08 22:01:06 2011

Main end

end==== m Mon 08 22:01:11 2011

That is, after the main process is finished, the child process is not over.

If we want the child process to end at the end of the main process, we should use the Setdaemon () function.

Examples are as follows:

The code is as follows:

Import threading, Time
Class MyThread (threading. Thread):
def __init__ (self, threadname = ""):
#threading. Thread.__init__ (self, name = ThreadName)
Super (MyThread, self). __init__ (name = ThreadName)
def run (self):
Print "starting====", Self.name, Time.ctime ()
Time.sleep (5)
Print "end====", Self.name, Time.ctime (),

m = MyThread ("M")
M.setdaemon (True)
M.start ()
Print "Main End"
Print


The result of the output is: Starting====main end m Mon 08 22:02:58 2011

As can be seen, and did not print out the sub-process m end of the time should have been printed "end=== ..."

Simple thread Synchronization

Execution threads often share data, but if it's okay to read only shared data, it can be unpredictable if multiple threads are modifying shared data.

If the two thread objects T1 and T2 are going to increment the numeric num=0 by 1, then the T1 and T2 will each be modified 10 times for NUM, then the final result of Num should be 20. However, if T1 gets the value of num (if num is 0 at this time), the system Dispatches T1 to the "sleeping" state, when T2 is converted to the "running" state, the value of num obtained by T2 is also 0, then he assigns the value of num+1 1 to Num. The system also converted T2 to "sleeping" state, T1 to "running" state, because T1 has been given a num value of 0, so he also assigned the value of num+1 to Num 1. It was a 2-time increase of 1 and the result was that NUM only increased 1 times. A situation like this can happen when multiple threads are executing simultaneously. Therefore, the thread synchronization mechanism is used to prevent such cases from appearing.

The simplest synchronization mechanism is the "lock"

Lock object with threading. Rlock class Creation

The code is as follows:

Mylock = Threading. Rlock ()

How do I use locks to synchronize threads? The thread can use the lock's acquire () (get) method so that the lock enters the "locked" state. Only one thread can get a lock at a time. If another thread attempts to acquire the lock, the system becomes "blocked" until the lock's release () (release) method is called by the locked thread, so that the lock enters the "unlocked" state. A thread in the "blocked" state receives a notification and has the right to obtain a lock. If multiple threads are in the "blocked" state, all threads will first de-blocked the state, then the system chooses one thread to obtain the lock, and the other threads continue to silence ("blocked").

The code is as follows:

Import threading
Mylock = Threading. Rlock ()
Class Mythread (threading. Thread)
...
def run (self ...):
... #此处 can not place code that modifies shared data
Mylock.acquire ()
... #此处 can place code that modifies shared data
Mylock.release ()
... #此处 can not place code that modifies shared data

The code that modifies the shared data is called a "critical section", and all critical sections must be enclosed between the acquire () and release () method invocations of the same lock object.

Locks can only provide the most basic level of synchronization. Sometimes more complex thread synchronization is required, such as accessing a critical section only when certain events occur (for example, when a value changes). This will use the condition variable.

The condition variable is used with threading. Condition class Creation

The code is as follows:

Mycondition = Threading. Condition ()

How does a conditional variable work? After a thread successfully obtains a condition variable, the Wait () method that invokes the condition variable causes the thread to release the lock and enter the "blocked" state until another thread invokes the Notify () method of the same condition variable to wake the thread that enters the "blocked" state. If the Notifyall () method of the conditional variable is called, all the waiting threads are awakened.

A deadlock can occur if the program or thread is always in the "blocked" state. Therefore, if the use of lock, condition variables, such as synchronization mechanism, must pay attention to carefully check to prevent the occurrence of deadlock situation. For critical sections that can produce exceptions, use the finally clause in the exception handling mechanism to guarantee the release of the lock. A thread that waits for a condition variable must be explicitly awakened with the Notify () method, or it will be silent forever. Make sure that every wait () method call has a corresponding notify () call, and of course you can call the Notifyall () method just in case.

Synchronization queue

We often use two threads of producer/consumer relationships to process data for a shared buffer. For example, a producer thread accepts user data into a shared buffer, waiting for a consumer thread to take the data out of the process. However, if the buffer is too small and the producer and consumer are not at the same speed as the two asynchronous threads, one thread is prone to wait for another condition. To minimize the waiting time for threads that share resources and work at the same speed, we can use a "queue" to provide additional buffers.

To create a "queue" object, you can use the following code:

The code is as follows:

Import Queue
Myqueue = queue.queue (maxsize = 10)


The Queue.queue class is a synchronous implementation of a queue. The queue length can be unlimited or limited. The queue length can be set through the optional parameter maxsize of the queue's constructor. If MaxSize is less than 1, it means that the queue length is infinite.

Put a value in the queue:

Myqueue.put (10)

The put () method of the call queue object inserts an item at the end of the team. Put () has two parameters, the first item is required, the value of the inserted item, the second block is an optional parameter, and the default is 1. If the queue is currently empty and the Block is the 1,put () method, the calling thread pauses until a data cell is vacated. If the block is the 0,put method, the full exception is thrown.

To remove a value from the queue:

Myqueue.get ()

The Get () method of the call queue object is removed from the team header and returns an item. The optional parameter is block, which defaults to 1. If the queue is empty and the Block is 1,get (), the calling thread is paused until a project is available. If the block is 0, the queue throws an empty exception.

Let's show you how to use a queue with an example:

The code is as follows:

# queue_example.py
From queue import queue
Import threading
Import Random
Import time

# Producer Thread
Class Producer (threading. Thread):
def __init__ (self, ThreadName, queue):
Threading. Thread.__init__ (self, name = ThreadName)
Self.sharedata = Queue
def run (self):
For I in range (20):
Print self.getname (), ' adding ', I, ' to queue '
Self.sharedata.put (i)
Time.sleep (Random.randrange (10)/10.0)
Print self.getname (), ' finished '

# Consumer Thread
Class Consumer (threading. Thread):
def __init__ (self, ThreadName, queue):
Threading. Thread.__init__ (self, name = ThreadName)
Self.sharedata = Queue
def run (self):
For I in range (20):
Print self.getname (), ' Got a value: ', Self.sharedata.get ()
Time.sleep (Random.randrange (10)/10.0)
Print self.getname (), ' finished '

# Main Thread
def main ():
Queue = Queue ()
Producer = producer (' producer ', queue)
consumer = consumer (' Consumer ', queue)

print ' Starting threads ... '
Producer.start ()
Consumer.start ()

Producer.join ()
Consumer.join ()

print ' All threads has terminated. '

if __name__ = = ' __main__ ':
Main ()


The result of the program output is:

Starting threads ...

Producer adding 0 to queue

Consumer got a value:0

Producer finished

Producer adding 1 to queue

Producer finished

Producer adding 2 to queue

Consumer finished

Consumer got a value:1

Consumer finished

Consumer got a Value:2

Consumer finished

Consumer got a value:producer finished

Producer adding 3 to queue

3

Consumer finished

Consumer got a value:producer finished

Producer adding 4 to queue

4

Consumerproducer finished

Consumerfinished

Got a value:producer adding 5 to queue

5

Consumer finished

Consumer got a value:producer finished

Producer adding 6 to queue

Producer finished

Producer adding 7 to queue

6

Consumer finished

Consumer got a Value:7

Producer finished

Producer adding 8 to queue

Producer finished

Producer adding 9 to queue

Consumer finished

Consumer got a Value:8

Consumerproducer finishedfinished

Consumerproducer got a value:adding 109

To queue

Producer finished

Producer adding to queue

Producer finished

Producer adding to queue

Consumerproducer finishedfinished

Consumerproducer got a value:adding 1310

To queue

Producer finished

Producer adding to queue

Consumer finished

Consumer got a value:11

Producer finished

Producer adding to queue

Producer finished

Producer adding to queue

Producer finished

Producer adding to queue

Producer finished

Producer adding to queue

Consumer finished

Consumer got a Value:12

Producer finished

Producer adding to queue

Producer finished

Consumer finished

Consumer got a value:13

Consumer finished

Consumer got a value:14

Consumer finished

Consumer got a value:15

Consumer finished

Consumer got a value:16

Consumer finished

Consumer got a value:17

Consumer finished

Consumer got a value:18

Consumer finished

Consumer got a value:19

Consumer finished

All threads has terminated.

Hopefully this article will help you with Python programming.

  • 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.