If you only use one hand to eat and drink soup, it takes fifteen minutes to eat and five minutes to drink soup, which will definitely take time. People want to open an LOL after eating early, so it’s very easy and we think of eating soup with our left hand and eating with our right hand at the same time. So the time to eat is optimized.

The topic of multithreading naturally revolves around the two keywords of process threads

Process of 1.

A quick word about processes: computer programs are simply executable binary (or other types of) files stored on disk. Read them from the hard drive into memory so you have a life cycle. A process, or heavyweight process (synonym), is an executing program that has its own address space, memory, data stack, and other auxiliary data for tracking execution. Our Operating System (OS) manages the execution of all processes and allocates a reasonable address space for these processes. Processes can also fork or spawn new processes, which of course have their own memory and stack, so interprocess communication (IPC) is the only way.

Thread 2.

Threads or lightweight processes (synonym) are similar to processes, but they execute under unified processes and share the same context, making it understandable that east and west threads in a process pool can be shared.

A thread consists of three parts: start — execute — end, and an instruction pointer is used to record the context in which it is currently running. It can be preempted (interrupted) and temporarily suspended (sleep) while other threads are running, a practice known as yielding.

Threads also have main threads, so each thread in a process shares a piece of data space with the main thread. If a lunch is a process, you can eat your own lunch but feel embarrassed to eat someone else’s (because eating someone else’s lunch requires communication (IPC communication) and getting hammered if you don’t communicate well!!). Eat what you wanteat what you want. Threads typically execute concurrently, and because of this concurrency and data sharing mechanism, collaboration between multiple tasks is possible.

Note: true concurrency is impossible on a single-core CPU, you can only grab one dish at a time, eat two bites and then grab another, and then come back to the same dish. Such an arbitrary order becomes a silent arrangement. The same goes for threads, one thread runs for a while and then sleeps, giving way to other threads (queuing up again for more CPU time). Throughout the process, each thread performs its own specific task and communicates the results with other threads as necessary.

This inevitably raises questions, and there are risks if data is shared.

Q1:

If two or more threads access the same piece of data, the data may be accessed in different order, resulting in inconsistent results. This situation is called a race condition. However, most thread libraries have synchronization primitives that allow control and access by thread managers.

Q2 :

Of course, there will always be a favorite dish to eat, so the amount of each dish will not be fair. That is, threads cannot give fair execution time. If you don’t have a specific multi-threaded case to modify, the CPU’s time allocation will skew toward a greedy function.

Here’s what I’m going to talk about:

Python thread

1.GIL (Global interpret lock) : Execution of Python code is controlled by the Python virtual machine (main interpreter loop). Only one thread of control can execute in the interpreter main loop, just like multiple processes on a single-cpu system. There can be many programs in memory, but only one program can be running at any given time. Although the Python interpreter can run multiple threads, only one thread is executed by the interpreter at any given time.

Access to the Python virtual machine is controlled by the global explain lock GIL, which is used to ensure that only one thread can run at a time.

The Python virtual machine will run as follows.

In Python multi-threading, each thread executes:

1. Obtain the GIL

Execute the code until sleep or the Python virtual machine suspends it.

Release GIL **

As you can see, in order to execute, a thread must first get the GIL. We can think of the GIL as a “pass”, and there is only one GIL in a Python process. Threads that do not get a pass are not allowed to enter the CPU for execution.

In Python2.x, the GIL is released when the current thread encounters an IO operation or when the ticks count reaches 100. This count can be adjusted by sys. setCheckInterval).

Each time the GIL lock is released, threads compete for the lock and switch threads, consuming resources. And because of the GIL lock, a process in Python can only execute one thread at a time, which is why python is not multithreaded efficiently on multi-core cpus.

So is multi-threading in Python completely useless? Here we have classified discussion: 1, cpu-intensive code (circulating processing, counting, etc.) in this case, because the calculation work, counting ticks will soon reach the threshold, and then trigger the release of GIL and competition (multiple threads to switch back and forth, of course, is the need to consume resources), so the multi-threading CPU intensive under the python code is not friendly.

2, IO intensive code (file processing, web crawler, etc.), multiple threads can effectively promote efficiency (IO operations will be under A single threaded IO wait, cause unnecessary waste of time, and can open multiple threads in the thread A waiting, automatically switch to the thread B, can not waste of CPU resources, thus can improve the program execution efficiency). So Multithreading in Python is friendly to IO intensive code.

2. Exit thread:

When a thread finishes executing a function, it exits. Threads can also be exited by an exit function such as Thread.exit (), or by a standard way of exiting a Python process such as sys.exit(), or by throwing a SystemExit exception. But you can’t just terminate a thread.

Main thread: The main thread should be a good manager to manage and schedule the meal (collect the results of each thread to produce a meaningful end result).

3. Using threads in Python:

The python interpreter we install is supported by default on the 64-bit computers we use every day, and only needs to import good modules to use it.

Thread: This module is not introduced or recommended because when the main thread terminates, all other threads are forced to terminate without warning or proper cleanup.

Threading: This module is often used because at least the threading module ensures that important child threads end before the process exits, also becoming daemons.

Look at a simple example

The following example is a basic example, without threads. It takes 5s to eat and 2s to drink soup, which is serial, and the parameter loop is the number of cycles.

Results:

According to the results, it took 4s to eat soup and 10s to eat, for a total of 14 seconds.

Join the threading module

Results:

Resolution:

Create an array of threads for Thread loading. Call the Thread() method of the Threading Module to create the Thread.

The results showed that eating and drinking soup were simultaneous. Start () starts thread activity, and join() waits for the thread to terminate. If you do not wait for each thread to terminate using the join() method, XXX will be printed out during thread execution.

The process of getting stronger is thinking about optimization, so we can optimize thread creation.

So we can focus on traversing the creation and then fine-tune the main function for this purpose, resulting in the following:

Results:

If there are some flaws, the part of print should be changed to I +1, and the loop times should also be forced to write 2 times. Of course, this is only a demo. If you consider adding a list to read in The Times parameter, you can add it to judge whether it is greater than zero, and you can try it yourself without further details.

In real development, the way we used threads was definitely not the way we used them, because we passed in a lot of arguments, so we had to use the Threading inheritance to create our own thread classes

I’m not going to show you the same results as before.

Over time, you’ll find that as you learn a little bit, your code will get better and better, and that’s how you think about it.

Since our cpus are currently multi-core, each process can have one thread executing. In Python, let’s try multi-processing to see the difference between multi-processing and multi-threading.

Multiprocessing module

Similar to the threading module, the Multiprocessing module provides local and remote concurrency, effectively using processes instead of threads through the GIL (global interpreter). Using multiple threads in a multi-core CPU is not an efficient way to take advantage of the CPU. Since each process in a CPU can only execute one thread at a time, it is possible to consider multiple processes to take advantage of multi-core cpus, both Unix and WIN are supported.

Change threading to Multiprocessing.

Result: Notice that I added a print PID number to the result to distinguish the process number.

That’s a clear distinction.

A PID is something like an ID card that represents a process. A process has a constant PID num before it ends, but the same process can have different PID num. For example, if you run this program twice more, you will find that the PID num is always changing, or if you run wechat on your computer, you will also find that the PID NUM is different.

As we can see from the above program, the use of multiprocessing is not very different from threading. There are also start(), run(), join(), and so on.

Take a look at the use of multiprocessing in the document, as shown below.

Target is the object to be called, args is the civilian parameter tuple of the object to be called, kwargs is the dictionary of the object to be called, name is an alias, Group is rarely used, and None is ok.

If you remove PID num, you won’t see any difference between Multiprocessing and threading from res. *

Multiprocessing Queue and pipe:

Since threads share data, they do not need to communicate, and this was mentioned earlier, so in the case of concurrent processes, processes need to communicate (IPC mechanism).

The common IPC supporting class Queue&Pipe transmits common objects. (1) PIPE is one-way and can also be two-way. Create a unidirectional Pipe with multiprocessing.Pipe(duplex=False).

Pipe objects are bidirectional by default. When it is created, a list of two elements is returned, each representing one end of the pipe (the Connection object). This has become the result of the code, ‘King of Heaven to cover tiger, chicken stew mushroom… No, the river demon of Pagoda Town. ‘

Send sends data, and the other end uses recV to receive data.

(2) The Queue class is similar to Pipe, but we all know that queues are first in, first out. A Queue allows multiple processes to be placed in and accessed from the Queue.

The most important thing to understand here is the use of this lock, just like the process in and out of the handcuffs do not let run, in and out of a clear, so that the printing is not very messy.