2021-10-15 python from introduction to mastery -- Chapter 18 processes and threads

Keywords: Python

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()

Posted by Thrakorzog on Sun, 17 Oct 2021 22:29:20 -0700