The memory of each program is independent, for example: world cannot access QQ.
Process: QQ is exposed to operating system management as a whole, which includes calls to various resources (memory management, network interface calls, etc.). Starting a QQ means starting a process.
A thread is the smallest unit that the operating system can perform calculation scheduling. Thread is included in Process and is the actual operating unit in the process.
There is at least one thread in a process.
A thread refers to a single sequence of control flow in a process.
A process of CAS runs multiple threads concurrently. Each thread executes different tasks in parallel. Threads are independent of each other.
Process: a collection of various resource management
Thread: the smallest scheduling unit of the operating system, which is a collection of instructions
The first thread in the process is the main thread. The main thread creates other threads. Other threads can also create threads. The threads are equal;
A process has a parent process, a child process, an independent memory space, a unique process identifier, and pid;
Context switching, also called process switching or task switching, refers to the CPU switching from one process or thread to another. For example, as follows:
a. Open QQ and WeChat, chat on QQ first, then switch to WeChat to chat, and then switch to QQ. This operation is called context switching.
b. Open multiple applications at the same time. The computer CPU configuration is 4 cores. When switching between multiple applications, there is no lag and no feeling that the CPU is switching tasks because the CPU processes quickly. , so there is no lag when switching between applications;
import timeimport requestsdef get_res(): urls = ['','','',''] start = time.time()for url in urls:print(url) resp = requests.get(url)print(resp) end = time.time()print('单线程运行时间:', end - start)
Execution result:
http://www.baidu.com<Response [200]>https://www.taobao.com/ <Response [200]>https://www.jd.com/ <Response [200]>http://www.meilishuo.com/ <Response [200]>单线程运行时间: 1.0470597743988037
a. The cpu is requested sequentially
b. Unless the cpu obtains a response from one url, it will not request the next url
c. Network requests take a long time, so the CPU remains idle while waiting for the return of network requests.
import timeimport threadingdef run(count):#每次执行该方法,需要休息2stime.sleep(2)print(count)#开始创建多线程start = time.time()for i in range(5):#创建线程,指定运行哪个函数,也就是指定哪个函数运行需要创建多线程#target=要运行的函数名# args=函数运行传入的参数,run方法需要传入count,把创建th = threading.Thread(target=run, args=(i, ))#启动线程 th.start()#多线程创建完毕且运行结束end = time.time()print('运行时间:', end - start)
Running results:
运行时间: 0.0 104 2 3
Explanation:
a. The printed running time does not count the running time of multi-threads, because you have to wait until you run. 2s, so the running time of multi-threading is at least 2s. So what is the printed result?
The printed running time is the running time of the main thread, because when running a python file, if multi-threading is not started, at least one thread is running
Threads are independent of each other. The main thread runs initially. When threading.Thread is reached, a thread is created. The created thread executes the loop method, and the main thread performs other operations
The main thread does not wait for other threads to finish before ending
b. The printed count data is unordered because multiple threads run run The method is not to make the next request after the first request is completed, but to create a thread and then execute the run method, and then create another thread, and the result will be printed out after which thread is executed
c. A total of 5 threads were created
If you want to count the total execution time of multi-threads, that is, the time from the beginning of creating a thread to the end of the thread (you do not need to consider how the threads running), the operation is as follows:
import timeimport threadingdef run(count):#每次执行该方法,需要休息2stime.sleep(2)print(count)#开始创建多线程start = time.time()#存放创建的所有线程threads_list = []for i in range(5):#创建线程,指定运行哪个函数,也就是指定哪个函数运行需要创建多线程#target=要运行的函数名# args=函数运行传入的参数,run方法需要传入count,把创建th = threading.Thread(target=run, args=(i, ))#启动线程 th.start()#把启动的每一个线程添加到线程组内 threads_list.append(th)for t in threads_list:#主线程循环等待每个子线程运行完毕, t代表每个子线程t.join() #等待线程结束#多线程创建完毕且运行结束end = time.time()print('运行时间:', end - start)
Execution result:
01 2 4 3运行时间: 2.0011146068573
Daemon thread: After the main thread ends, it will end regardless of whether the daemon thread execution ends. For example:
For example, the emperor has many servants. When the emperor dies, then If you have many servants, you will be buried with them.
As long as the non-daemon thread ends, regardless of whether the daemon thread ends or not, the program ends
import threadingimport timedef run(count): time.sleep(2)print(count)for i in range(5):#循环创建线程,总共5个线程t = threading.Thread(target=run, args=(i, ))#设置守护线程,新创建的这些线程都是 主线程的 守护线程, 主线程创建一个线程后 就运行结束了 t.setDaemon(True)#启动线程,守护线程设置必须在start前面 t.start()print('over')
例如 4核机器上
Python创建4线程,四个线程均匀分到多核上,但是同时只能一核在处理数据。
python调用操作系统、C语音的原生接口,在出口做了设置。全局解释器锁,保证数据统一
所以有人说python的线程是假线程。
在修改数据的时候,为了防止数据改乱了,所以多线程就变成串行处理,但是以为是python在处理,实际上是调用了操作系统的C语音的线程接口,所以中间的过程,python控制不了了,只知道结果。在这种情况下,设置的方式是出口控制,虽然四个线程,但是同一时间只有一个线程在工作。
所以这算是python的一个缺陷,但是也不能说是python的缺陷,是Cpython的缺陷。因为Cpython是C语音写的,以后python的未来是PYPY。
线程锁,又叫互斥锁
线程之间沟通:保证同一时间只有一个线程修改数据
python2.x 中需要加锁,Python3.x中加不加锁都一样,因为解释器做了优化
import threadingfrom threading import Lock#创建lock对象num = 0 lock = Lock() #申请一把锁,创建锁的对象def run2():global num lock.acquire() #修改数据前 加锁num += 1lock.release() #修改后释放解锁lis = []for i in range(5):#创建线程t = threading.Thread(target=run2)#启动线程 t.start()#将启动的线程添加到线程组内 lis.append(t)for t in lis:#等待线程运行结束 t.join()#num的值为5,执行多次后,会出现不一样的值print('over', num)
大锁中还有小锁、递归锁,解锁时就混了,所以用递归锁,Rlock()
import threading,timedef run1():print("grab the first part data") lock.acquire()global num num +=1lock.release()return numdef run2():print("grab the second part data") lock.acquire()global num2 num2+=1lock.release()return num2def run3(): lock.acquire() res = run1()print('--------between run1 and run2-----') res2 = run2() lock.release()print(res,res2)if __name__ == '__main__': num,num2 = 0,0 lock = threading.RLock() # 声明递归锁# lock = threading.Lock() # 用互斥锁,会锁死了,弄混锁情况,可以试一下for i in range(10): t = threading.Thread(target=run3) t.start()while threading.active_count() != 1:print(threading.active_count())else:print('----all threads done---')print(num,num2)
import threadingimport timeclass MyThread(threading.Thread):def __init__(self, num): threading.Thread.__init__(self) self.num = numdef run(self): # 定义每个线程要运行的函数print("running on number:%s" % self.num) time.sleep(3)if __name__ == '__main__': t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start()
python里面的多线程,是不能利用多核cpu的,如果想利用多核cpu的话,就得使用多进程
多进程适用CPU密集型任务
多线程适用io密集型任务
from multiprocessing import Processdef f(name): time.sleep(2)print('hello', name)if __name__ == '__main__':for i in range(10): p = Process(target=f, args=('niu',)) p.start()
The above is the detailed content of What is a process? What is a thread?. For more information, please follow other related articles on the PHP Chinese website!