简单多线程

python的多线程是伪并发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import threading

def print1(name):
for i in range(10000):
print('1:',threading.currentThread())

def print2(name):
for i in range(10000):
print('2:',threading.currentThread())

t1=threading.Thread(target=print1,args=('xjb',))
t2=threading.Thread(target=print2,args=('ruyi',))

t1.setDaemon(True)
t2.setDaemon(True)

t1.start()
t2.start()

print('t1:',t1.daemon) # 查看t1是否为守护线程,返回false就不是守护线程
print('t2:',t2.daemon)
#守护线程 线程都是你主线程的附庸 你结束我就结束kill
#非守护线程 你主线程结束和我没关系 我要自己执行完才会结束

print('主程序结束',threading.currentThread(),threading.main_thread())
# print1()
# print2()

多线程上锁

比如全局变量的加减同时进行,如果不加锁的话,最后的结果是不定的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#操作原子性   原子   最小的不可切分的过程
#num=num+1 两部分 加法 赋值
#牺牲时间 增加安全

# 1 -1 1

import threading

Lock=threading.Lock()

num=0

def add():
global num
for i in range(1000000):
Lock.acquire()
num+=1
Lock.release()

def sub():
global num
for i in range(1000000):
Lock.acquire()
num -= 1
Lock.release()

t1=threading.Thread(target=add)
t2=threading.Thread(target=sub)

t1.start()
t2.start()

t1.join()
t2.join()

print('num:',num)

进程和进程池

同步和异步的区别是同步得等执行的函数返回结果之后才会继续循环,异步是不等结果返回,只要有进程空闲就往后执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import multiprocessing
import time

def num(name):
print('run process {}'.format(name))
time.sleep(3)
print('process {} end'.format(name))

if __name__ == '__main__':
#进程池 我在一开始就创建好一个袋子 N个进程 哪个空闲哪个就拿出来直接用
Pools=multiprocessing.Pool(3)

for i in range(10):
#Pools.apply(func=num,args=(i,))#apply 同步
Pools.apply_async(func=num, args=(i,))#apply_async 异步

Pools.close()#进程池不再接收任何新的任务了
Pools.join()

print('主进程结束.')

python协程异步

异步就是在单线程中,利用系统的等待时间,在这个等待时间期间去做别的事

比如访问一个网页,网页要3秒返回,不可能在这个时间内什么都不做,可以去请求访问别的网页

协程可以理解为没有并发起来的任务,协程本身不会多个并发,需要手动处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import asyncio

async def num(name):
print('{} start'.format(name))
await asyncio.sleep(2)
print('{} end'.format(name))

async def main():
t1=[num(1),
num(2),
num(3)]
await asyncio.gather(*t1)

if __name__ == '__main__':
#声明协程对象 并不会直接运行
num(1)
#对于协程对象,如果不加await,都是声明,而不是执行
#await运行协程任务 等待 会一直阻塞到任务结果返回
asyncio.run(main())

多进程代理数据共享

就是如何去操作同一个对象

multiprocessing.Manager()相当于创建了一个服务器代理,所有对目标对象的操作都是通过这个代理去操作的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import multiprocessing
import time

def push(li,lock):
print(id(li))
while 1:
print('正在存放数据')
lock.acquire()
li.append("xjb")
time.sleep(1)
lock.release()

def pop(li,lock):
print(id(li))
while 1:
if li:
lock.acquire()
print('我正在拿数据'+str(li.pop()))
time.sleep(1)
lock.release()

def main():
#不是共享内存,是代理服务器操作
li=multiprocessing.Manager().list()
#对于代理服务器,其实lock不是必须的
lock=multiprocessing.Manager().Lock()

print(id(li))
p1=multiprocessing.Process(target=push,args=(li,lock,))
p2 = multiprocessing.Process(target=pop, args=(li,lock,))
p1.start()
p2.start()
p1.join()
p2.join()

if __name__ == '__main__':
main()