The relationship and differences between processes, threads, and concurrencies have been bugging me for a while as well, and I've recently had some insights to write about.
Processes have their own independent heap and stack, neither share the heap nor the stack, and processes are scheduled by the operating system.
Threads have their own separate stack and shared heap, shared heap, not shared stack, and threads are also scheduled by the operating system (standard threads yes).
Concurrent threads share the heap, not the stack, as do threads, and concurrent threads are scheduled by the programmer shown in the code of the concurrent thread.
The difference between the process and the other two is still clear.
The difference between a concatenation and a thread is that a concatenation avoids pointless scheduling, and thus improves performance, but also, as a result, the programmer has to take responsibility for scheduling on his own, and concatenations lose the ability to use multiple CPUs with standard threads.
Python threads
Definition : Threading is used to provide thread-related operations; a thread is the smallest unit of work in an application.
#!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time def show(arg): (1) print 'thread'+str(arg) for i in range(10): t = (target=show, args=(i,)) () print 'main thread stop
The above code creates 10 "foreground" threads, and then the controller hands them over to the CPU, which schedules them according to a specified algorithm and executes the instructions in pieces.
More ways:
-Start thread is ready for CPU scheduling.
-setName Sets the name for the thread
-getName Get thread name
-setDaemon Set to background thread or foreground thread (default)
If it is a background thread, during the execution of the main thread, the background thread is also in progress, and after the main thread finishes executing, the background thread stops regardless of whether it succeeds or not
If it is a foreground thread, during the execution of the main thread, the foreground thread is also in progress, and after the main thread finishes executing, the program stops after waiting for the foreground thread to finish executing as well
-join executes each thread one at a time, and then continues on to the next, which makes multithreading meaningless.
-run Automatically executes the thread object's run method when the thread is dispatched by the cpu.
thread lock
Since threads are randomly scheduled with each other, and each thread may execute only n executions, the CPU then executes other threads. Therefore, the following problems may occur.
import threading import time gl_num = 0 def show(arg): global gl_num (1) gl_num +=1 print gl_num for i in range(10): t = (target=show, args=(i,)) () print 'main thread stop' import threading import time gl_num = 0 lock = () def Func(): () global gl_num gl_num +=1 (1) print gl_num () for i in range(10): t = (target=Func) ()
event
Python thread events are used by the main thread to control the execution of other threads. events provide three main methods set, wait, and clear.
Mechanism of event handling: A "Flag" is defined globally, if the value of "Flag" is False, then the program will block when executing the method, if the value of "Flag "value is True, then the method will not block.
-clear: Set the "Flag" to False.
-set: Set the "Flag" to True.
#!/usr/bin/env python # -*- coding:utf-8 -*- import threading def do(event): print 'start' () print 'execute' event_obj = () for i in range(10): t = (target=do, args=(event_obj,)) () event_obj.clear() inp = raw_input('input:') if inp == 'true': event_obj.set()
Python process
from multiprocessing import Process import threading import time def foo(i): print 'say hi',i for i in range(10): p = Process(target=foo,args=(i,)) ()
Note: Since each process needs to hold a copy of the data between them, there is a very large overhead required to create processes.
Process data sharing
Processes each hold a copy of the data and cannot share data by default
#!/usr/bin/env python #coding:utf-8 from multiprocessing import Process from multiprocessing import Manager import time li = [] def foo(i): (i) print 'say hi',li for i in range(10): p = Process(target=foo,args=(i,)) () print ('ending',li)
# Method I, Array
from multiprocessing import Process,Array temp = Array('i', [11,22,33,44]) def Foo(i): temp[i] = 100+i for item in temp: print i,'----->',item for i in range(2): p = Process(target=Foo,args=(i,)) ()
#Method II: () Sharing data
from multiprocessing import Process,Manager manage = Manager() dic = () def Foo(i): dic[i] = 100+i print () for i in range(2): p = Process(target=Foo,args=(i,)) () () 'c': ctypes.c_char, 'u': ctypes.c_wchar, 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, 'h': ctypes.c_short, 'H': ctypes.c_ushort, 'i': ctypes.c_int, 'I': ctypes.c_uint, 'l': ctypes.c_long, 'L': ctypes.c_ulong, 'f': ctypes.c_float, 'd': ctypes.c_double
When the process is created (not in use), the shared data is taken to the child process, and then assigned to the original value when execution in the process is complete.
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process, Array, RLock def Foo(lock,temp,i): """ Add 100 to the 0th digit """ () temp[0] = 100+i for item in temp: print i,'----->',item () lock = RLock() temp = Array('i', [11, 22, 33, 44]) for i in range(20): p = Process(target=Foo,args=(lock,temp,i,)) ()
process pool
The process pool maintains a sequence of processes, and when used, a process is fetched from the pool. If there is no process in the pool sequence that can be used, the program waits until a process is available in the pool.
There are two methods in the process pool:
•apply
•apply_async
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process,Pool import time def Foo(i): (2) return i+100 def Bar(arg): print arg pool = Pool(5) #print (Foo,(1,)) #print pool.apply_async(func =Foo, args=(1,)).get() for i in range(10): pool.apply_async(func=Foo, args=(i,),callback=Bar) print 'end' ()
()# Close processes in the process pool after they have finished executing, if commented out then the program closes directly
concurrent program
Threads and processes operate by programs triggering the system interface, and the final executioner is the system; co-programs operate by programmers.
The significance of the existence of concatenation: For multi-threaded applications, the CPU switches the execution between threads by slicing, and the thread switching is time consuming (save the state and continue next time). Concurrent threads, on the other hand, use only one thread to specify the order of execution of a block of code in a single thread.
Scenarios where concatenation is applicable: when there are a large number of operations in the program that do not require the CPU (IO), concatenation is applicable;
greenlet
#!/usr/bin/env python # -*- coding:utf-8 -*- from greenlet import greenlet def test1(): print 12 () print 34 () def test2(): print 56 () print 78 gr1 = greenlet(test1) gr2 = greenlet(test2) ()
gevent
import gevent def foo(): print('Running in foo') (0) print('Explicit context switch to foo again') def bar(): print('Explicit context to bar') (0) print('Implicit context switch back to bar') ([ (foo), (bar), ])
Automatically switches when an IO operation is encountered:
from gevent import monkey; monkey.patch_all() import gevent import urllib2 def f(url): print('GET: %s' % url) resp = (url) data = () print('%d bytes received from %s.' % (len(data), url)) ([ (f, '/'), (f, '/'), (f, '/'), ])
The above is a small introduction to the knowledge of processes, threads, and co-programs in Python, I hope it will help you!