Processes && Threads
Process: A stand-alone handle in memory that we can understand as an application in memory is a process. Each process is memory-independent, non-shareable
Threads: Each application runs after a main thread is started, and the main thread can create multiple word threads, each of which shares the memory space of the main process.
There is an interesting and vivid explanation of threads and processes (http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html)
GIL (Global interpreter Lock)
We know that multi-process (mutilprocess) and multi-threaded (threading) are designed to be accessed by multiple CPUs to improve program execution efficiency. But within Python there is a mechanism (GIL) that allows only one thread to access the CPU at the same time at multiple threads.
The GIL is not a Python feature, it is a concept introduced when implementing the Python parser (CPython). Just like C + + is a set of language (syntax) standards, but can be compiled into executable code with different compilers. Well-known compilers such as Gcc,intel c++,visual C + +.
Python is the same, and the same piece of code can be executed through different Python execution environments such as Cpython,pypy,psyco. Like the Jpython there is no Gil. However, because CPython is the default Python execution environment for most environments. So in a lot of people's concept CPython is Python, also take for granted the GIL to the Python language flaw. So let's be clear here: Gil is not a Python feature, and Python can be completely independent of the Gil.
Although Python supports multithreading, because of the Gil's limitations, when the program is actually running, multiple threads are opened, but only one thread can be executed by the CPU after the Gil.
Multithreading
1) Multithreading Execution method
import timefrom threading import Threaddef do_thread(num): print("this is thread %s" % str(num)) time.sleep(3)for i in range(5): t = Thread(target=do_thread, args=(i,)) t.start()
The above method opens a 5 thread, target is used to define the method to be executed after the thread is opened, and args is the parameter
Other methods of threading:
1 SetName (), GetName ()
SetName (): Set a name for the thread
GetName (): Gets the name of the thread
import timefrom threading import Threaddef do_thread(num): print("this is thread %s" % str(num)) time.sleep(3)for i in range(2): t = Thread(target=do_thread, args=(i,)) t.start() t.setName("Mythread_{0}".format(str(i))) print(t.getName())run result: this is thread 0 Mythread_0 this is thread 1 Mythread_1
2 Setdaemon ()
Setdaemon (True/false): Sets the child thread created as a foreground thread or a background thread. Set to True if the child thread is a background thread. Line Cheng think foreground thread (not set this method)
Foreground thread: When the child thread is created, the main thread and the child thread (foreground thread) run concurrently, and if the main thread finishes executing and the child threads are not completed, the entire program will not end until the child thread finishes executing.
Background thread: When the child thread is created, if the child thread is not finished, and the main thread runs the end without a pipe thread, the program ends.
This method setting must be set before the start () method to see the code:
import timefrom threading import Threaddef do_thread(num): print("this is thread %s" % str(num)) time.sleep(3) print("OK", str(num))for i in range(2): t = Thread(target=do_thread, args=(i,)) # 不设置此方法默认前台线程, #t.setDaemon(True) t.setName("Mythread_{0}".format(str(i))) t.start() print(t.getName())run result:this is thread 0Mythread_0this is thread 1Mythread_1OK 0OK 1import timefrom threading import Threaddef do_thread(num): print("this is thread %s" % str(num)) time.sleep(3) # 执行到此时主线程执行完了,程序结束,下面的代码不会执行 print("OK", str(num))for i in range(2): t = Thread(target=do_thread, args=(i,)) # 设置线程为后台线程 t.setDaemon(True) t.setName("Mythread_{0}".format(str(i))) t.start() print(t.getName())run result:this is thread 0Mythread_0this is thread 1Mythread_1
3 Join ()
Join (Timeout): Multi-threaded wait (), when the main thread executes a child thread. After the join () method, the main thread waits for the child thread to finish executing. When the timeout parameter is added, if the timeout time is exceeded, the pipe thread will end up waiting until it finishes executing.
Take a look at the following two examples
When there is no join method above, the main thread finishes executing print and waits for print execution to complete in the child thread function, and the program exits. Let's look at the effect after adding the Join method
import timefrom threading import Threaddef do_thread(num): time.sleep(3) print("this is thread %s" % str(num))for i in range(2): t = Thread(target=do_thread, args=(i,)) t.setName("Mythread_{0}".format(str(i))) t.start() t.join() print("print in main thread: thread name:", t.getName())run result:this is thread 0print in main thread: thread name: Mythread_0this is thread 1print in main thread: thread name: Mythread_1
When the program runs to join, it waits for the subroutine to finish before executing down. So the program becomes a single-threaded sequential execution. Multithreading is no use for birds.
What is the difference between join () and Setdaemon () are waiting for the end of a child thread:
When a join () is executed, the main thread stops until the child thread completes and then the main thread executes, and the entire program is linear
When Setdaemon () is the foreground thread, all threads are running concurrently and the main thread is running. Just wait for all child threads to end after the main thread has finished running. This is still a parallel execution, and the execution efficiency is definitely higher than the join () method.
4-Wire Lock
Threads are memory-shared and can cause threads to scramble when multiple threads operate on the same public variable in memory, and in order to resolve this issue, the thread lock is used.
import timeimport threadingdef do_thread(num): global public_num # 加锁 lock.acquire() public_num -= 1 # 解锁 lock.release() time.sleep(1) print("public_num in thread_%s is %s" % (str(num), str(public_num)))public_num = 100threads_list = []lock = threading.Lock()for i in range(50): t = threading.Thread(target=do_thread, args=(i,)) t.setName("Mythread_{0}".format(str(i))) t.start() threads.append(t) # 等待所有子线程结束for t in threads: t.join()print("last result of public_num is ", public_num)
5 Event ()
The thread's event, which is used for the main thread to control the execution of the child thread. Its essence is to define a global flag identity, and to obtain and set this identity by some means. Including:
Wait () method: When the flag is identified as false, the wait () method will block, when True, wait () does not block
Set () Method: Sets flag ID to True
Clear () Method: Set flag ID to False
Flag is marked false when initializing (blocking state)
Is_set ()/isset (): Determines whether the current flag ID is true
import threadingdef do(event): print(‘start‘) # 默认初始化状态为False,到这里就阻塞了 event.wait() print(‘execute\n‘)if __name__ == "__main__": event_obj = threading.Event() for i in range(10): t = threading.Thread(target=do, args=(event_obj,)) t.start() inp = input(‘input:‘) if inp == ‘true‘: # 如果为true,则flag=True,不阻塞,子进程继续运行 event_obj.set() else: event_obj.clear()
Event An example of a simulated traffic light:
def light(): linght_time = 0 if not event.is_set(): event.set() # Flag = True, 阻塞 while True: time.sleep(1) if linght_time < 10: print("Green is on....") elif linght_time < 13: print("Yellow is on ....") elif linght_time < 16: print("Red is on ......") if event.is_set(): event.clear() else: # 大于16, 该重新调绿灯了 linght_time = 0 event.set() linght_time += 1def car_run(carnum): while True: time.sleep(2) if event.is_set(): print("car %s is run" % carnum) else: print("CAR %s IS WAITTING........" % carnum)if __name__ == "__main__": event = threading.Event() l = threading.Thread(target=light, ) l.start() for i in range(3): c = threading.Thread(target=car_run, args=(str(i), )) c.start()
6) Semaphore ()
Semaphore Semaphore Management a built-in counter:
Built-in counter whenever acquire () is called-1;
Built-in counter +1 when call Release ();
The counter cannot be less than 0, and when the counter is 0 o'clock, acquire () blocks the thread until another thread calls release ().
import threadingimport timedef do(): semaphro.acquire() print("this is {0} set the semaphore".format(threading.current_thread().getName())) time.sleep(2) semaphro.release() print("\033[1;30mthi is {0} release the semaphore\033[0m".format(threading.current_thread().getName()))if __name__ == "__main__": semaphro = threading.Semaphore(2) for i in range(10): t = threading.Thread(target=do) t.setName("Thread_{0}".format(str(i))) t.start() print("finished")
In the example above, although 10 threads were created, only 2 threads were running, because 2 semaphores were set through semaphore in the thread. Only one of the other threads can start executing after the release
Welcome to my public number: Python Learning communication, welfare both hands Oh!
Welcome to join my thousand People Exchange learning questions: 125240963
Python's most detailed 0 basic primer-multi-threaded details!