先看个误打误撞的写的代码

import os
import time
import multiprocessing
def func():
print('我是func函数1','现在的father进程号为:',os.getppid())
time.sleep(2)
print('我是func函数2,但是我休息了2秒','现在的father进程号为:',os.getppid()) print('打酱油1','现在的进程号为:',os.getpid())
p=multiprocessing.Process(target=func())
if __name__=='__main__':
p.start()
print('打酱油2','现在的进程号为:',os.getpid())
print('end-------','现在的进程号为:',os.getpid())
'''输出结果
打酱油1 现在的进程号为: 7112
我是func函数1 现在的father进程号为: 4088
我是func函数2,但是我休息了2秒 现在的father进程号为: 4088
打酱油2 现在的进程号为: 7112
end------- 现在的进程号为: 7112
打酱油1 现在的进程号为: 3456
我是func函数1 现在的father进程号为: 7112
我是func函数2,但是我休息了2秒 现在的father进程号为: 7112
end------- 现在的进程号为: 3456'''

自己不小心把函数名给行进去了,然后发现很奇怪,就一直在这里改啊改,然后就出现了上面的一串奇怪的代码,所以说很奇怪。好吧,先看看下边的发现总结。

说明 4088 是pycharm的运行的进程号

7112是父的进程号

3456是子的进程号

1.运行的顺序是先父然后子进程。

2.因为在给子进程写的时候,不小心把子进程的()也写进去了,所以调用了子进程。这样的调用而且好像是子进程是全部父进程的的代码(后面试验后发现确实如此),不知道不加if __name__=='__main__'是不是全部运行父进程的代码。

3.老师特别强调在windows中才必需加上if __name__=='__main__',然后放在下面执行,不知道什么意思,所以以后用其他系统检验下。老师说不加这段代码可能会报错。

下面开始进入正题

process 的模块的介绍

process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调: 1. 需要使用关键字的方式来指定参数

2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

参数介绍: 1 group参数未使用,值始终为None

2 target表示调用对象,即子进程要执行的任务

3 args表示调用对象的位置参数元组,args=(1,2,'egon',)

4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}

5 name为子进程的名称

1 p.start():启动进程,并调用该子进程中的p.run()

2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法

3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁

4 p.is_alive():如果p仍然运行,返回True

5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程

1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置

2 p.name:进程的名称

3 p.pid:进程的pid

4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)

5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)

多进程的几种方法:

1.用函数去调

import time
from multiprocessing import Process
def process():
print('woshozojinchen')
if __name__=='__main__':
print('it is father process')
p=Process(target=process)
p.start()
time.sleep(5)
print('end')

2.用类方法去调

import os
import time
from multiprocessing import Process
class Myserver(Process):
def __init__(self,name,age):
super(Myserver,self).__init__()
self.name=name
self.age=age
def run(self): print('this is a Preocess and it is Process number',os.getpid())
print('father process number:',os.getppid())
time.sleep(0.1)
print(self.__dict__)
if __name__=='__main__':
print('it is father Process',os.getpid())
p1=Myserver('alex',1)
p1.start()
time.sleep(0.09)
print('end')

比较两种的差异:

1.用函数去调时不要加上括号,传时候用元祖去传,而用类的方法去调时,直接是实例化即可,注意用类去掉时一定要加上run的方法,因为start其实就是在调用类的start的方法,但是要注意在__init__时要写上super来继承父类的参数

join的用法

import os
from multiprocessing import Process
from time import sleep
class myserver(Process):
def __init__(self,filename,i):
super(myserver,self).__init__()
self.i =i
self.filename=filename
def run(self):
with open(self.filename,'w')as f:
f.write('it is a question ')
# sleep(0.2)
print('*'*10*self.i,self.i)
if __name__=='__main__':
lis=[]
for i in range(10):
p=myserver('info%s'%i,i)
p.start()
print('p nameL:',p.name)
print(p)
lis.append(p) print(lis)
print('it is end')
p nameL: myserver-1
<myserver(myserver-1, started)>
p nameL: myserver-2
<myserver(myserver-2, started)>
p nameL: myserver-3
<myserver(myserver-3, started)>
p nameL: myserver-4
<myserver(myserver-4, started)>
p nameL: myserver-5
<myserver(myserver-5, started)>
p nameL: myserver-6
<myserver(myserver-6, started)>
p nameL: myserver-7
<myserver(myserver-7, started)>
p nameL: myserver-8
<myserver(myserver-8, started)>
p nameL: myserver-9
<myserver(myserver-9, started)>
p nameL: myserver-10
<myserver(myserver-10, started)>
[<myserver(myserver-1, started)>, <myserver(myserver-2, started)>, <myserver(myserver-3, started)>, <myserver(myserver-4, started)>, <myserver(myserver-5, started)>, <myserver(myserver-6, started)>, <myserver(myserver-7, started)>, <myserver(myserver-8, started)>, <myserver(myserver-9, started)>, <myserver(myserver-10, started)>]
it is end
******************** 2
********** 1
****************************** 3
**************************************** 4
********************************************************************** 7
************************************************************ 6
****************************************************************************************** 9
******************************************************************************** 8
************************************************** 5

输出结果

从上面可以看出来输出的结结果比较混乱,而且注意P的输出是个方法,不是p

如果想等子进程的代码执行完毕之后在执行后面的代码,这时就需要join的登场了

第一种方法

import os
from multiprocessing import Process
from time import sleep
class myserver(Process):
def __init__(self,filename,i):
super(myserver,self).__init__()
self.i =i
self.filename=filename
def run(self):
with open(self.filename,'w')as f:
f.write('it is a question ')
# sleep(0.2)
print('*'*10*self.i,self.i)
if __name__=='__main__':
lis=[]
for i in range(10):
p=myserver('info%s'%i,i)
p.start()
print('p nameL:',p.name)
print(p)
lis.append(p)
a=[i.join()for i in lis]
print(a)
print(lis)
print('it is end')
p nameL: myserver-1
<myserver(myserver-1, started)>
p nameL: myserver-2
<myserver(myserver-2, started)>
p nameL: myserver-3
<myserver(myserver-3, started)>
p nameL: myserver-4
<myserver(myserver-4, started)>
p nameL: myserver-5
<myserver(myserver-5, started)>
p nameL: myserver-6
<myserver(myserver-6, started)>
p nameL: myserver-7
<myserver(myserver-7, started)>
p nameL: myserver-8
<myserver(myserver-8, started)>
p nameL: myserver-9
<myserver(myserver-9, started)>
p nameL: myserver-10
<myserver(myserver-10, started)>
********************************************************************** 7
************************************************************ 6
******************** 2
******************************************************************************** 8
****************************** 3
********** 1
****************************************************************************************** 9
0
************************************************** 5
**************************************** 4
[None, None, None, None, None, None, None, None, None, None]
[<myserver(myserver-1, stopped)>, <myserver(myserver-2, stopped)>, <myserver(myserver-3, stopped)>, <myserver(myserver-4, stopped)>, <myserver(myserver-5, stopped)>, <myserver(myserver-6, stopped)>, <myserver(myserver-7, stopped)>, <myserver(myserver-8, stopped)>, <myserver(myserver-9, stopped)>, <myserver(myserver-10, stopped)>]
it is end

输出结果

可以看见实现了上诉的功能,用列表的形式去实现所得join功能。相当于实现了列表里面的join代码

第二种方法

import os
from multiprocessing import Process
from time import sleep
class myserver(Process):
def __init__(self,filename,i):
super(myserver,self).__init__()
self.i =i
self.filename=filename
def run(self):
with open(self.filename,'w')as f:
f.write('it is a question ')
# sleep(0.2)
print('*'*10*self.i,self.i)
if __name__=='__main__': for i in range(10):
p=myserver('info%s'%i,i)
p.start()
print('p nameL:',p.name)
print(p)
p.join()
i
p name: myserver-1
<myserver(myserver-1, started)>
0
p name: myserver-2
<myserver(myserver-2, started)>
********** 1
p name: myserver-3
<myserver(myserver-3, started)>
******************** 2
p name: myserver-4
<myserver(myserver-4, started)>
****************************** 3
p name: myserver-5
<myserver(myserver-5, started)>
**************************************** 4
p name: myserver-6
<myserver(myserver-6, started)>
************************************************** 5
p name: myserver-7
<myserver(myserver-7, started)>
************************************************************ 6
p name: myserver-8
<myserver(myserver-8, started)>
********************************************************************** 7
p name: myserver-9
<myserver(myserver-9, started)>
******************************************************************************** 8
p name: myserver-10
<myserver(myserver-10, started)>
****************************************************************************************** 9
it is end

输出结果

可以看见在循环中加入join,这样在每次的循环中就能依次输出了。但是通过输出结果可以发现输出的结果很有顺序,也就是说每次执行完了,才开始下次的循环,因为相当于join的后面是跟着for循环的,所以我不太推荐这种循环,还不如直接写在主程序里,感觉区别不大。这样写完全没有体现多线程的有优点。

注意join一定要写在for循环里面,否则只有最后一个子线程跟在主线程的后面。

数据隔离

import os
from multiprocessing import Process def func():
global n # 声明了一个全局变量
n = 0 # 重新定义了一个n
print('pid : %s'%os.getpid(),n) if __name__ == '__main__':
n = 100
p = Process(target=func)
p.start()
p.join()
print(os.getpid(),n)
pid : 4148 0
7636 100

输出结果

父进程的变量是不与子进程共享的

守护进程

import time
from multiprocessing import Process def func():
while True:
time.sleep(0.2)
print('我还活着') def func2():
print('in func2 start')
time.sleep(8)
print('in func2 finished') if __name__ == '__main__':
p = Process(target=func)
p.daemon = True # 设置子进程为守护进程
p.start()
p2 = Process(target=func2)
p2.start()
# time.sleep(1.1)
p2.terminate() # 结束一个子进程
time.sleep(1)
print(p2.is_alive()) # 检验一个进程是否还活着
print(p2.name)
time.sleep(0.9)
我还活着
我还活着
我还活着
我还活着
False
Process-2
我还活着
我还活着
我还活着
我还活着
我还活着

输出结果

守护进程 会 随着 主进程的代码执行完毕 而 结束
在主进程内结束一个子进程 p.terminate()
结束一个进程不是在执行方法之后立即生效,需要一个操作系统响应的过程,即刚执行结束代码时,在检验is alive可能返回的是Ture.所以上面的代码是先睡上1秒后在检验使才返回的的是false
检验一个进程是否活着的状态 p.is_alive()

必须在p.start()之前设置

p.name p.pid 这个进程的名字和进程号

lock锁

import json
from time import sleep
from multiprocessing import Process
from multiprocessing import Lock
def buy_ticket(i,lock):
lock.acquire()
sleep(1)
with open('ticket','r')as f:
msg=json.load(f)
if msg['ticket']>0:
msg['ticket']-=1
print('\033[32myou buy a ticket\033[0m')
elif msg['ticket']<=0:
print('\033[31myou not buy a ticket\033[0m')
with open('ticket','w')as f:
json.dump(msg,f)
lock.release()
if __name__=='__main__':
lock=Lock()
with open('ticket','w')as f:
msg={'ticket':1}
json.dump(msg,f)
for i in range(10):
p = Process(target=buy_ticket,args=(i,lock))
p.start()

lock

you buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket
you not buy a ticket

输出结果

上面的代码是模仿买火车票,买火车票是必须是一个一个的买,如果所有人有一下能进入数据库的话,那么可能会造成数据的更新不够及时,而造成票被多买。所以需要一把锁来约束,让用户一个一个的买,注意的是上锁的过程必须是先导入模块,然后在定义这个模块,然后定义的函数就必须多传两个参数,及(i,lock),然后在函数中的必须写上一个拿锁的过程和释放锁的过程。

多线程——multiprocess的更多相关文章

  1. python 多线程和多进程基本写法

    #coding=utf-8 def aJob(arg): """ 提供给多线程调用 """ import threading t = thr ...

  2. Python的多线程(threading)与多进程(multiprocessing )

    进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...

  3. 多线程的学习与python实现

    学习了进程与线程,现对自己的学习进行记录. 目录: 一.进程与线程的概念,以及联系与区别 二.多线程 三.python中多线程的应用 四.python实例 五.参考文献 一.进程与线程的概念.以及联系 ...

  4. 【python】多进程锁multiprocess.Lock

    [python]多进程锁multiprocess.Lock 2013-09-13 13:48 11613人阅读 评论(2) 收藏 举报  分类: Python(38)  同步的方法基本与多线程相同. ...

  5. [转载] Python的GIL是什么鬼,多线程性能究竟如何

    原文: http://cenalulu.github.io/python/gil-in-python/ GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器( ...

  6. 『Python』 多线程 端口扫描器

    0x 00 Before Coding 当端口打开时,向端口发送 TCP SYN 请求,会返回一个 ACK 响应: 当端口关闭,返回的是 RST 响应: 0x 01 Coding  可以用 socke ...

  7. 【Python3之多线程】

    一.threading模块 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性. 1.开启线程的两种方式(同Process) 方法一 from thr ...

  8. python 多线程和多进程的区别 mutiprocessing theading

    多线程可以共享全局变量,多进程不能.多线程中,所有子线程的进程号相同:多进程中,不同的子进程进程号不同. #!/usr/bin/python # -*- coding:utf-8 -*- import ...

  9. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

随机推荐

  1. Spring AOP实现统一日志输出

    目的: 统一日志输出格式 思路: 1.针对不同的调用场景定义不同的注解,目前想的是接口层和服务层. 2.我设想的接口层和服务层的区别在于: (1)接口层可以打印客户端IP,而服务层不需要 (2)接口层 ...

  2. asp.net core 系列 17 通用主机 IHostBuilder

    一.概述 ASP.NET Core 通用主机 (HostBuilder),该主机对于托管不处理 HTTP 请求的应用非常有用.通用主机的目标是将 HTTP 管道从 Web 主机 API 中分离出来,从 ...

  3. Android Hybrid App自动化测试实战讲解(基于python)

    1.Hybrid App自动化测试概要 什么是Hybrid App? Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具“Native App ...

  4. 剖析HBase负载均衡和性能指标

    1.概述 在分布式系统中,负载均衡是一个非常重要的功能,在HBase中通过Region的数量来实现负载均衡,HBase中可以通过hbase.master.loadbalancer.class来实现自定 ...

  5. 【c#】RabbitMQ学习文档(四)Routing(路由)

    (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ,这个功能是我们将只订阅消息的一个子集成为可能. 例 ...

  6. REST API设计指导——译自Microsoft REST API Guidelines(三)

    前面我们说了,如果API的设计更规范更合理,在很大程度上能够提高联调的效率,降低沟通成本.那么什么是好的API设计?这里我们不得不提到REST API. 关于REST API的书籍很多,但是完整完善实 ...

  7. C#_实现冒泡排序

    //排序方法类public class Bubble { ; public static void SBubble(ref int[] intArr) { ; outSize < intArr. ...

  8. Mysql 连接数,最大并发数设置

    项目中可能会遇到MySQL: ERROR 1040: Too many connections”的异常情况,造成这种情况的一种原因是访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散 ...

  9. Java学习笔记之——多线程

    多线程编程 程序: 进程:一个程序运行就会产生一个进程 线程:进程的执行流程,一个进程至少有一个线程,称为主线程 如:QQ聊着天,同时在听音乐 一个进程可以有多个线程,多个线程共享同一个进程的资源 线 ...

  10. python爬虫项目-爬取雪球网金融数据(关注、持续更新)

    (一)python金融数据爬虫项目 爬取目标:雪球网(起始url:https://xueqiu.com/hq#exchange=CN&firstName=1&secondName=1_ ...