Using processes and threads
process
Create process
Creating a process using the multiprocessing module
Process([group [, target [, name [, args [, kwargs]]]]])
group: the parameter is not used, and the value is never None
target: indicates the callable object executed when the current process starts
name: indicates the alias of the current process instance
args: represents the parameter tuple passed to the target function
kwargs: represents the parameter dictionary passed to the targe function
Example:
form multiprocessing import Process def test(interval): print("I am a subprocess") def main(): print("Main process start") p=Process(target=test, args = (1, )) p.start() print("End of main process") if __name__ == "main": main()
- is_alive(): judge whether the process instance is still executing
- join([timeout]): wait for the execution of the process instance to end. How many seconds
- start(): start the process instance
- run(): if the target parameter is not given, when the start() method is called on this object, the run method in the object is executed
- terminate(): terminate immediately
- name: current process instance alias
- PID: the PID value of the current process instance
Create a Process using the Process subclass
For simple tasks, Process(target = test) is usually used to implement multiple processes
To handle complex tasks, you usually define a class that inherits the Process class
from multiprocessing import Process import time import os #Inherit Process class class SubProcess(Process): #Overridden the of the parent class__ init__ () method def __init__(self, interval, name = ""): Process.__init__(self) #Call the initialization method of the Process parent class self.interval = interval #Added its own content if name: self.name = name #Rerun () method def run(self): t_start = time.time() time.sleep(self.interval) t_stop = time.time() if __name__ = "__main__": p1 = SubProcess(interval = 1, name = "mrsoft") p2 = SubProcess(interval = 2) p1.start() #Start process p1 p2.start() #Start process P2 p1.join() #Wait for the p1 process to end p2.join() #Wait for the p2 process to end
Create a process using the process Pool
When creating multiple processes, use the pool class in the multiprocess module
- apply_async(func[, ags[, kwds]]): call func function in non blocking mode. args is the parameter list passed to func function and kwds is the keyword parameter list passed to func function
- apply(func[, args[, kwds]]): call func function in blocking mode
- close(): close the pool so that it will no longer receive new tasks
- terminate(): terminate immediately
- join(): the main process is blocked and waits for the child process to exit. It must be used after close or terminate
from multiprocessing import Pool import os, time def task(name): print("Subprocess%s implement task %s"%(os.getpid(), name)) time.sleep(1) if __name__ = "__main__": p = Pool(3) for i in range(10): p.apply_async(task, args(i,)) p.close() p.join()
Interprocess communication
queue
fifo
Use of multi process queues
The Queue of multiprocessing module can be used to realize data transfer between multiple processes
- q = Queue(num): initialization. If num is 0 or negative, it means that there is no upper limit on the number of messages received
- q.qsize(): returns the number of messages contained in the current queue
- q.empty(): determines whether the queue is empty. If it is empty, it returns True
- q.full(): judge whether the queue is full. If it is full, it will be True
- q.get([block[, timeout]]): get messages in the queue. Block is True by default
Block = true & & timeout not set: block in read state when message queue is empty
Block = true & & set timeout: timeout time. If the message queue is not empty, the Queue.Empty exception will be thrown
block = False: if the message queue is not empty, the Queue.Empty exception will be thrown immediately - q.get_nowait(): equivalent to q.get(False)
- q.put(item, [block[, timeout]]): writes the item message to the queue. Block is True by default
Block = true & & timeout not set: the message queue is blocked in write state when there is no space to write
Block = true & & set timeout: wait for timeout. If there is no space, throw Queue.Full exception
block = False: throw Queue.Full exception immediately when the message queue has no space to write - q.put_nowait(item): equivalent to q.put(item, False)
Example:
from multiprocessing import Queue if __name__ = "__main__": q = Queue(3) q.put("message1") q.put("message2") q.put("message3") try: q.put("message4", True, 2) except: print("Queue Full,count:%s"%q.qsize()) if not q.empty(): for i in range(q.size()): print(q.get_nowait()) if not q.full(): q.put_nowait("message4")
Use queues to communicate between processes
Example:
from multiprocessing import Process, Queue import time def write_task(q): if not q.full(): for i in range(5): message = "msg" + str(i) q.put(message) def read_task(q): time.sleep(1) while not q.empty(): print(q.get(True, 2)) if __name__ = "__main__": q = Queue() pw = Process(target = write_task, args = (q, )) pr = Process(target = read_task, args(q, )) pw.start() pr.start() pw.join() pr.join()
thread
Create thread
Creating threads using the threading module
Thread([group [, target [, name [, args [, kwargs]]]]])
- group: the value is always None
- target: represents a callable object. When the thread starts, the run() method will call this object
- Name: indicates the name of the current thread
- args: represents the parameter tuple passed to the target function
- kwargs: represents the parameter dictionary passed to the target function
Example:
import threading, time def process(): for i in range(3): time.sleep(1) priint("thread name is %s"%threading.current_thread().name) if __name__ = "__main__": threads = [threading.Thread(target = process) for i in range(4)] #Create 4 threads and store them in the list for t in threads: t.start() #Open thread for t in threads: t.join() #Wait for the child thread to end
Create a Thread using the Thread subclass
import threading, time #Create a subclass SubThread, inherit the threading.Thread thread thread class, instantiate the thread, and automatically call the parent class__ init__ () method class SubThread(threading.Thread): def run(self): for i in range(3): time.sleep(1) msg = "Child thread" + self.name + str(i) #Name stores the name of the current thread print(msg) if __name__ = "__main__": t1 = SubThread() t2 = SubThread() t1.start() t2.start() t1.join() t2.join()
Inter thread communication
Sharing global variables between threads
mutex
Since all threads can change global variables at will, a mutex lock is required to prevent multiple threads from accessing the same piece of memory at the same time
Use mutex
There are two methods in the Lock class, acquire() Lock and release()
mutex = threading.Lock() #Create lock mutex.acquire([blocking]) #locking mutex.release() #release
Inter process communication using queues
Use the same method as in-process queues
from queue import Queue import random, threading, time class Producer(threading.Thread): def __init__(self, name, queue): threading.Thread.__init__(self.name = name) self.data = queue def run(self): for i in range(5): print("%s, %d"%(self.getName(), i)) self.data.put(i) time.sleep(random.random()) class Consumer(threading.Thread): def __init__(self, name, queue): threading.Thread.__init__(self, name = name) self.data = queue def run(self): for i in range(5): val = self.data.get() print("%s, %d"%(self.getName(), val)) time.sleep(random.random()) if __name__ == "__main__": queue = Queue() producer = Producer("Producer", queue) consumer = Consumer("Consumer", queue) producer.start() consumer.start() producer.join() consumer.join()