1 并发和并行的理解?
并发: 在一段时间内交替的去执行任务
并行:对于多核cpu处理多任务,操作系统给每一个cpu安排一个执行的软件,多个内核是真正的一起执行的软件。
2 多进程的使用:
正常的情况下是fn函数执行完以后才会执行fn1这个函数,但是fn这个函数又是一个死递归,所以fn1这个函数就无法执行。
def fn(): while True: print(1111) time.sleep(1) def fn1(): print(222) fn() fn1() 这里执行的就是 1111 11111 。。。 创建多进程,来让函数同时执行
import multiprocessing import time def fn(): while True: print(1111) time.sleep(1) def fn1(): print(222) if __name__ == '__main__': f = multiprocessing.Process(target=fn) f1 = multiprocessing.Process(target=fn1) f.start() f1.start()
这里的代码执行的顺序就是 1111 222 1111 11111 ..., 进程的执行是无序的,具体哪个函数先执行要看操作系统先运行哪一个。
3 获取当前主进程的编号
if __name__ == '__main__': print(multiprocessing.current_process()) # <_MainProcess name='MainProcess' parent=None started>
4 获取当前子进程的编号
if __name__ == '__main__': f = multiprocessing.Process(target=fn) print(f) # <Process name='Process-1' parent=18264 initial> f1 = multiprocessing.Process(target=fn1) print(f1) # <Process name='Process-2' parent=18264 initial> f.start() f1.start()
5 修改子进程编号的名称: name
if __name__ == '__main__': f = multiprocessing.Process(target=fn,name="AAA") print(f) # <Process name='AAA' parent=12316 initial> f1 = multiprocessing.Process(target=fn1,name='BBB') print(f1) # <Process name='BBB' parent=12316 initial>
6 第二种获取当前子进程的编号:
def fn(): print(multiprocessing.current_process()) # <Process name='Process-1' parent=23068 started> while True: print(1111) time.sleep(1)
7 获取当前进程的父进程标号
def fn(): print(os.getppid()) # 获取当前父进程的标号 while True: print(1111) time.sleep(1)
8 根据进程的id编号 杀死自己的进程 :
def fn3(): while True: print('333') time.sleep(2) os.kill(os.getpid(),9) #根据当前进程的id编号 杀死自己的进程
9 进程传参:args kwargs
f = multiprocessing.Process(target=fn,args=('ls',20))
f1 = multiprocessing.Process(target=fn1,kwargs={'name':'zs'})
f2 = multiprocessing.Process(target=fn1,args = ('ls'), kwargs={'age':12})
10 子进程之间不会共享全局的数据
import multiprocessing import time list1 = [] def fn(): for i in range(10): list1.append(i) time.sleep(1) def fn1(): for i in range(10): print(list1) # [] [] [] time.sleep(1) if __name__ == '__main__': m1 = multiprocessing.Process(target=fn) m2 = multiprocessing.Process(target=fn1) m1.start() m2.start()
11 强制让某一个进程先执行完 在执行下面的进程
if __name__ == '__main__': m1 = multiprocessing.Process(target=fn) m2 = multiprocessing.Process(target=fn1) m1.start() m1.join() # 让上一个进程先执行 这个进程执行完之后再执行下一个进程 m2.start()
12 把子进程设置为守护主进程 主进程退出子进程直接销毁
if __name__ == '__main__':
m1 = multiprocessing.Process(target=fn)
m1.daemon = True # 把子进程设置为守护主进程 主进程退出子进程直接销毁
m1.start()
第二种方式 退出主进程之前先让子进程销毁
m1.terminate()
13 关于线程:
一个进程有多个线程 也是有一个主线程。 线程是用来执行代码的。
import threading import time def fn(): print('1') def fn1(): print('2') if __name__ == '__main__': f = threading.Thread(target=fn) f1 = threading.Thread(target=fn1) f.start() f1.start()
14 获取当前线程的编号
第一种方式: print(threading.current_thread()) # 获取主线程的编号 def fn(): print(threading.current_thread()) # <Thread(Thread-1 (fn), started 26388)> print('1') 第二种方式: if __name__ == '__main__': f = threading.Thread(target=fn) f1 = threading.Thread(target=fn1) print(f) # <Thread(Thread-1 (fn), initial)> print(f1) # <Thread(Thread-2 (fn1), initial)>
15 线程传递参数:
def fn(num): print(threading.current_thread()) # <Thread(Thread-1 (fn), started 26388)> print(num) def fn1(name): print('2') if __name__ == '__main__': f = threading.Thread(target=fn,args=(1)) f1 = threading.Thread(target=fn1,kwargs={'name':'zs'})
16 子线程会等主线程结束之后再结束
17 子线程守护主线程 主线程结束子线程销毁 :daemo=True 主线程不会等子线程执行完再结束了
if __name__ == '__main__': threading.Thread(target=fn,daemon=True).start() time.sleep(2) print('223')
也可以通过设置 f1.setDaemon(True) 守护父线程
if __name__ == '__main__':
f1 = threading.Thread(target=fn)
f1.setDaemon(True)
time.sleep(2) print('223')
18 线程之间共享全局的变量
import threading import time list1 = [] def fn(): for i in range(10): list1.append(i) print(list1,'1') def fn1(): for i in range(10,20): list1.append(i) print(list1,'2') #[0, 1, 2, 3, 10, 11, 12, 13, 4, 5, 6, 7, 14, 15, 8, 16, 17, 9, 18, 19] if __name__ == '__main__': threading.Thread(target=fn).start() threading.Thread(target=fn1).start()
19 让当前的线程先执行完再执行下一个线程 f.join()
if __name__ == '__main__': f = (threading.Thread(target=fn)) f.start() f.join() f1 = threading.Thread(target=fn1).start()
20 线程之间共享全局变量数据错误的问题
解决方法就是 线程等待jion() 还有就是互斥锁
import threading import time lock = threading.Lock() 创建锁 list1 = [] def fn(): lock.acquire() 上锁 for i in range(10): list1.append(i) print(list1,'1') lock.release() 解锁 def fn1(): lock.acquire() 上锁 for i in range(10,20): list1.append(i) print(list1,'2') lock.release() 解锁 if __name__ == '__main__': f = (threading.Thread(target=fn)) f.start() f1 = threading.Thread(target=fn1).start()
21 死锁等对方一直释放锁的情景:比如判断条件不符合直接退出了条件没有释放锁
import threading lock = threading.Lock() def fn(index): lock.acquire() my_list = [1,2,3,4] if index>=len(my_list): print(index) lock.release() # 在不符合条件之前解锁 return value = my_list[index] print(value) lock.release() if __name__ == '__main__': for i in range(10): print(i) f = threading.Thread(target=fn,args=(i,)) f.start()