각 프로그램의 메모리는 독립적입니다. 예: 세계는 QQ에 액세스할 수 없습니다.
프로세스: QQ는 다양한 리소스에 대한 호출(메모리 관리, 네트워크 인터페이스 호출 등)을 포함하여 운영 체제 관리 전체에 노출됩니다. QQ를 시작한다는 것은 프로세스를 시작한다는 것을 의미합니다.
스레드는 운영 체제에서 계산 스케줄링을 수행할 수 있는 가장 작은 단위입니다. 스레드는 프로세스에 포함되며 프로세스의 실제 작동 단위입니다.
프로세스에는 하나 이상의 스레드가 있습니다.
스레드는 프로세스의 단일 순차적 제어 흐름을 나타냅니다.
CAS의 프로세스는 여러 스레드를 동시에 실행합니다. 각 스레드는 서로 다른 작업을 병렬로 실행하며 스레드는 서로 독립적입니다.
프로세스: 다양한 자원 관리의 집합
스레드: 운영 체제의 가장 작은 일정 단위, 명령어 집합
첫 번째 스레드가 프로세스 메인 스레드는 다른 스레드를 생성하고 다른 스레드도 스레드를 생성할 수 있으며 스레드는 동일합니다.
프로세스에는 상위 프로세스, 하위 프로세스, 독립 메모리 공간, 고유 프로세스 식별자, pid가 있습니다. ;
프로세스 전환 또는 작업 전환이라고도 하는 컨텍스트 전환은 CPU가 한 프로세스나 스레드에서 다른 프로세스나 스레드로 전환하는 것을 의미합니다. 예를 들면 다음과 같습니다.
a. QQ와 WeChat을 열고 먼저 QQ에서 채팅한 다음 WeChat으로 전환하여 채팅한 다음 QQ로 전환하는 작업을 합니다.
b. 동시에 여러 응용 프로그램을 엽니다. 컴퓨터 CPU 구성은 4코어입니다. 여러 응용 프로그램 간에 전환할 때 CPU가 작업을 빠르게 처리하기 때문에 지연이 없습니다. 시간 간 전환 시 지연이 없습니다.
단일 스레드:
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)
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
c. 네트워크 요청에 시간이 오래 걸리기 때문에 네트워크 요청 반환을 기다리는 동안 CPU가 유휴 상태였습니다.
멀티스레딩:
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)
运行时间: 0.0 104 2 3
a 인쇄된 실행 시간 통계는 멀티 스레드의 실행 시간이 아닙니다. 실행하기 전에 2초를 기다려야 하므로 멀티 스레드의 실행 시간은 최소 2초, 그러면 인쇄된 결과는 무엇입니까?
인쇄된 실행 시간은 메인 스레드의 실행 시간입니다. Python 파일을 실행할 때 멀티스레딩이 시작되지 않으면 적어도 하나의 스레드가 실행되고 있기 때문입니다.
스레드는 처음에는 서로 독립적입니다. 실행중인 것은 메인 스레드입니다.thread로 실행하면 스레드가 생성됩니다. 생성된 스레드는 루프 메서드를 실행하고 메인 스레드는 다른 작업을 수행합니다
메인 스레드는 다른 스레드가 실행될 때까지 기다리지 않습니다. 종료 전에 완료
b 다중 스레드가 실행 메소드를 실행할 때 첫 번째 요청이 완료된 후 다음 요청이 이루어지지 않고 대신 스레드가 생성되고 실행 메소드가 실행되기 때문에 인쇄된 카운트 데이터가 정렬되지 않습니다. , 그리고 또 다른 스레드가 생성됩니다. 스레드가 실행된 후 결과가 인쇄됩니다 c. 총 5개의 스레드가 생성되었습니다
멀티 스레드의 총 실행 시간을 계산하려면 즉, 스레드 생성 시작부터 스레드 종료까지의 시간(스레드 실행 방법을 고려할 필요 없음)이며 작업은 다음과 같습니다.
join() wait(스레드가 끝날 때까지 대기)
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)
01 2 4 3运行时间: 2.0011146068573
데몬 스레드
데몬 스레드가 아닌 스레드가 종료되는 한, 데몬 스레드의 종료 여부에 관계없이 프로그램은 종료됩니다
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()
위 내용은 프로세스란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!