并发编程(一)

一.计算机发展史

  多道技术

    1.空间上的复用:多个程序共用一套计算机硬件

    2.时间上的复用

       切换+保存状态

        1.当一个程序遇到IO操作  操作系统会剥夺该程序的CPU执行权限(提高了CPU的利用率)

        2.当一个程序长时间占用CPU,操作系统也会剥夺其执行权限(降低了程序的执行效率)

二.进程的理论

程序:一堆代码      进程:正在运行的程序

1.同步异步:表示的是任务的提交方式

  同步:任务提交之后 原地等待的任务的执行并拿到返回结果再走  期间不做任何事情(程序的表面就是卡住了)

  异步:任务提交之后 不在原地等待,而是继续执行下一行代码(结果是要的,但是是用过其他方式获取

2.阻塞非阻塞:表示的程序的运行状态

  阻塞:阻塞态,在等待

  非阻塞:就绪态,运行态

强调:同步异步  阻塞非阻塞是两对概念  不能混为一谈

三.创建进程的两种方式

创建进程就是在内存中重新去开辟一块内存空间, 将允许产生的代码丢进去

一个进程对应在内存就是一块独立的内存空间

进程与进程之间数据是隔离的 无法直接交互 但是可以通过某些技术实现间接交互

第一种:

 1 import multiprocessing  import Process
 2 import time
 3 def test():
 4     print('子进程 is running!')
 5     time.sleep(2)
 6     print('子进程 is over!')
 7 
 8 if __name__ == '__main__':
 9     p = Process(target = test)
10     p.start()
11     print('父进程')

第二种:

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super.__init__()
        self.name = name

    def run(self):
        print("%s is running" %self.name)
        time.sleep(3)
        print('%s is over' %self.name)

if __name__ == '__main__':
    p = MyProcess('子进程')
    p.start()
    print('主进程')

四.进程方法join

 1 from multiprocessing import Process
 2 import time
 3 
 4 def test(name,i):
 5     print('%s is running'%name)
 6     time.sleep(i)
 7     print('%s is over'%name)
 8 
 9 if __name__ == '__main__':
10      p_list= []
11     for i in range(3):
12         p = Process(target = test,args =('进程%s'%i,i))
13         p.start()
14         p_list.append(p)
15    for p in p_list:
16         p.join() #主进程代码等待子进程运行结束 才继续运行
17         #主进程代码等待子进程运行结束
18     print('主进程')

五.进程间数据是隔离的

一个进程对应在内存就是一块独立的内存空间

进程与进程之间数据是隔离的 无法直接交互

 1 from multiprocessing import Process
 2 import time
 3 
 4 money = 100
 5 
 6 def test():
 7     global money
 8     money = 9999
 9 
10 if __name__ =='__main__':
11     p = Process(target = test)
12     p.start()
13     p.join()
14     print(money)  #结果还是100  进程与进程之间数据隔离的 都是各自的独立内存空间

六.进程对象及其他方法

 1 from multiprocessing import Process,current_process
 2 import os
 3 import time
 4 
 5 def test():
 6     print('子进程')
 7     print(current_process().pid)
 8     print(os.getpid())   #两个都是一个意思  查询当前进程的 id
 9     print(os.getppid()) #获取父进程的id
10     time.sleep(3)
11     print('子进程 is over')
12 
13 if __name__ == '__main__':
14     p = Process(target = test)
15     p.start()
16     p.terminate()  #杀死当前进程  其实就是告诉操作系统 帮你杀死一个进程
17     time.sleep(0.1)
18     print(p.is_alive()) #判断进程是否活着   结果 False
19     print(os.getpid())
20     print(os.getppid()) #主进程的父进程就是执行它的程序进程id 例如parcharm

七.僵尸进程 与孤儿进程

1.僵尸进程

结束的进程就是僵尸进程,所有的进程都会步入僵尸进程

僵尸进程 虽然结束了 但是他有id号等需要回收 这回收的工作需要交给它的父进程来做

父进程回收子进程资源的两种方式:

  1.join方法

  2.父进程正常死亡

2.孤儿进程

  子进程没死,而父进程意外死亡

  针对linux会有儿童福利院(init)来收养父进程意外死亡他所创建的子进程

八.守护进程

 1 from multiprocessing import Process
 2 import time
 3 
 4 def test(name)
 5     print('%s总管正常活着'%name)
 6     time.sleep(3)
 7     print('%s总管正常死亡'%name)
 8 
 9 if __name__ == '__main__':
10     p = Process(target = test,args = ('egon',))
11     p.daemon = True  #将该进程设置为守护进程,这一句话必须要放在start前面,否则将会报错
12     time.sleep(0.1)
13     print('皇帝驾崩')

九.互斥锁

用抢票来举例子,如果多个人同时抢一张票的话,肯定是要看手速和网速。那么如果多个进程同时去操作抢票的话,怎么能够将他们区分先后顺序呢。这里用到了互斥锁。

当多个进程操作同一份数据的时候 会造成数据的错乱

这个时候必须加锁处理  将并发变为串行

  虽然降低了效率 但是提高了数据的安全

  注意:

    1.锁不要轻易使用 容易造成死锁现象

    2.只在处理数据的部分加锁,不要在全局加锁

  锁必须在主进程中产生 交给子进程去使用

 1 from multiprocessing import Process,Lock
 2 import time
 3 imort json
 4 
 5 #查票
 6 def search(i):
 7     with open ('data','r',encoding = 'utf-8') as f:
 8         data = f.read()
 9     t_d = json.loads(data)
10     print('用户%s查询余票为%s' %(i,t_d.get('ticket')))
11 
12 #买票
13 def buy(i):
14     with open ('data','r',encoding = 'utf-8') as f:
15         data = f.read()
16     t_d = json.loads(data)
17     time.sleep(1)
18     if t_d.get('ticket')>0:
19         t_d['ticket'] -= 1
20         with open('data','w',encoding='utf-8') as f:
21             json.dump(t_d,f)
22         print('用户%s抢票成功'%i)
23     else:
24         print('没票了')
25 
26 
27 def run(i,mutex):
28     search(i)
29     mutex.acquire()  # 抢锁  只要有人抢到了锁 其他人必须等待该人释放锁
30     buy(i)
31     mutex.release()  # 释放锁
32 
33 
34 if __name__ == '__main__':
35     mutex = Lock()  # 生成了一把锁
36     for i in range(10):
37         p = Process(target=run,args=(i,mutex))
38         p.start()

操作的data

{“ticket”:1}

猜你喜欢

转载自www.cnblogs.com/s686zhou/p/11329770.html