Process 类
创建进程:
1. p = Process( target= callable , name= '' , args= '' , kwargs= '' )
2. p. start( ) 启动进程
一、
主进程:执行的时候,默认的进程称作主进程
子进程:在主进程中可以开启子进程
p1 = Process( target= callable , args= '' )
os. getpid( ) 当前进程
os. getppid( ) 父进程
二、全局变量
如果是全局变量则,每个进程都会拥有一份全局变量。各自操作各自的全局变量
三、阻塞主进程
子进程. join( )
阻塞主进程后面的代码
import time
import os
from multiprocessing import Process
def task1 ( ) :
global number
for i in range ( 5 ) :
print ( '洗衣服:' , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
number -= 10
print ( '洗衣服:' , number)
def task2 ( n) :
global number
for i in range ( n) :
print ( '劳动最光荣,扫地中...' , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
number -= 8
print ( '扫地:' , number)
number = 100
if __name__ == '__main__' :
print ( 'main:--->start' , os. getpid( ) )
p1 = Process( target= task1)
p2 = Process( target= task2, args= ( 6 , ) )
p1. start( )
p2. start( )
p1. join( )
p2. join( )
print ( 'main:--->end' , os. getpid( ) )
print ( 'main中的number是:' , number)
进程对象可以访问方法:
run( )
start( )
join( )
terminate( )
close( ) target完成之后调用的close( ) 释放资源
is_alive( ) 判断target任务是否完成,如果任务完成则False ,没有完成True (是否是活动的)
def task1 ( ) :
for i in range ( 5 ) :
print ( '洗衣服:' , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
def task2 ( n) :
for i in range ( n) :
print ( '劳动最光荣,扫地中...' , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
if __name__ == '__main__' :
p1 = Process( target= task1)
p2 = Process( target= task2, args= ( 6 , ) )
p1. start( )
p2. start( )
for i in range ( 10 ) :
if i == 4 :
p1. terminate( )
elif i == 5 :
p2. terminate( )
time. sleep( 0.3 )
print ( 'main:' , i)
p2. close( )
print ( "p1是否活着:" , p1. is_alive( ) )
print ( "p2是否活着:" , p2. is_alive( ) )
** 进程池: **
Pool
** 阻塞式
非阻塞式:**
def task1 ( ) :
print ( '洗衣服:' , os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
return '我是进程:' + str ( os. getpid( ) )
def callback ( msg) :
print ( '{}洗衣服任务完成!' . format ( msg) )
if __name__ == '__main__' :
pool = Pool( 4 )
for i in range ( 10 ) :
pool. apply_async( task1, callback= callback)
pool. close( )
pool. join( )
print ( 'main over' )
** 阻塞式**
from multiprocessing import Pool
def task1 ( ) :
for i in range ( 5 ) :
print ( '洗衣服:' , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
if __name__ == '__main__' :
pool = Pool( 4 )
for i in range ( 10 ) :
pool. apply ( task1)
print ( '------------------------->' , i)
pool. close( )
pool. join( )
print ( 'main over' )
进程间通信与信号量
队列:
FIFO
put( ) : 队列中存放,如果满了则阻塞
get( ) : 从队列中取值,如果空了则阻塞
full( ) 判断是否是满了
empty( ) 判断是否是空了 如果空了,True
qsize( ) 获取长度
from multiprocessing import Process, Queue
queue = Queue( 3 )
queue. put( '馒头1' )
queue. put( '馒头2' )
queue. put( '馒头3' )
print ( queue. full( ) )
print ( queue)
print ( queue. qsize( ) )
try :
queue. put( '馒头4' , timeout= 3 )
queue. put( '馒头5' , timeout= 3 )
except :
print ( '存放馒头失败' )
while True :
try :
print ( queue. get( timeout= 1 ) )
except :
print ( '队列为空,取不出东西' )
break
用process实现分进程网上下载图片:
p = Process( target= func(函数名), name= '' , args= ( 参数) , kwargs= { } )
def download ( urls, queue) :
for image_url in urls:
response = requests. get( image_url)
image_data = response. content
queue. put( image_data)
def save_file ( queue) :
count = 0
while True :
try :
data = queue. get( timeout= 5 )
filename = 'img' + str ( count) + '.jpg'
with open ( 'images/' + filename, 'wb' ) as ws:
ws. write( data)
count += 1
print ( '保存{}完毕!' . format ( filename) )
except Exception as err:
print ( '没有更多数据啦!' )
break
if __name__ == '__main__' :
q1 = Queue( 2 )
images = [
'https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=7bf3ea52d40735fa85fd46ebff3864d6/8644ebf81a4c510f0912aa536059252dd52aa5a1.jpg' ,
'https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=aa62e3280fb30f242197e451a9fcba26/eaf81a4c510fd9f906c11d20252dd42a2934a4a1.jpg'
]
p1 = Process( target= download, args= ( images, q1) )
p2 = Process( target= save_file, args= ( q1, ) )
start = time. time( )
p1. start( )
p2. start( )
p1. join( )
p2. join( )
end = time. time( )
print ( '用时:{}秒' . format ( end - start) )
用重写run方法实现下载图片:
class DownloadProcess ( Process) :
def __init__ ( self, urls, queue) :
Process. __init__( self)
self. urls = urls
self. queue = queue
def run ( self) :
for image_url in self. urls:
filename = os. path. split( image_url) [ 1 ]
response = requests. get( image_url)
image_data
= response. content
self. queue. put( image_
data)
self. queue. get( )
print ( '下载{}完毕' . format ( filename) )
self. queue. close( )
if __name__ == '__main__' :
q1 = Queue( 2 )
images = [
'https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=7bf3ea52d40735fa85fd46ebff3864d6/8644ebf81a4c510f0912aa536059252dd52aa5a1.jpg' ,
'https: // gss1. bdstatic. com/ 9vo3dSag_xI4khGkpoWK1HF6h
hy/ baike/ c0% 3Dbaike92% 2C5% 2C5% 2C92% 2C30/ sign= aa62e3280fb30f242197e451a9fcba26/ eaf81a4c510fd9f906c11d20252dd42a2934a4a1. jpg'
]
dlprocess = DownloadProcess( images, q1)
dlprocess. start( )
for i in range ( 5 ) :
if dlprocess. is_alive( ) :
print ( '进程是活跃的:' , i)
else :
print ( '进程结束了' )
dlprocess. close( )
break
time. sleep( 0.5 )
** python 如何创建一个线程?**
** 线程:**
1. t1 = Thread( target= task1)
2. 自定义线程
run( )
start( )
join( )
name: 默认的Thread- 1 , Thread- 2 , . . . .
current_thread( ) . name 获取当前线程的名字
is_alive
'''
python 如何创建一个线程?
线程:
1. t1 = Thread(target=task1)
2. 自定义线程
run()
start()
join()
name: 默认的Thread-1, Thread-2,....
current_thread().name 获取当前线程的名字
is_alive
'''
import os
import time
from threading import Thread, current_thread
def task1 ( ) :
for i in range ( 5 ) :
print ( '{}洗衣服:' . format ( current_thread( ) . name) , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
def task2 ( n) :
for i in range ( n) :
print ( '{}劳动最光荣,扫地中...' . format ( current_thread( ) . name) , i, os. getpid( ) , os. getppid( ) )
time. sleep( 0.5 )
if __name__ == '__main__' :
print ( 'main:' , os. getpid( ) )
t1 = Thread( target= task1, name= '警察' )
t2 = Thread( target= task2, name= '小偷' , args= ( 6 , ) )
t1. start( )
t2. start( )
for i in range ( 3 ) :
print ( "t1:" , t1. is_alive( ) )
print ( "t2:" , t2. is_alive( ) )
print ( 'main:' , i)
time. sleep( 1 )
** 自定义线程: **
1. 定义一个类继承Thread
2. 重写: [ __init__] 必须重写: run( )
3. 创建线程类对象
4. 启动线程
class MyThread ( Thread) :
def __init__ ( self, name) :
Thread. __init__( self)
self. name = name
def run ( self) :
for i in range ( 5 ) :
print ( '{}正在打印:{}' . format ( self. name, i) )
time. sleep( 0.1 )
if __name__ == '__main__' :
t1 = MyThread( '小明' )
t2 = MyThread( '小花' )
t3 = MyThread( 'ergou' )
t1. start( )
t2. start( )
t3. start( )
共享数据:
如果有全局变量,则每个线程是共享的。
GIL:
ticket = 10
def sale_ticket ( ) :
global ticket
while True :
if ticket > 0 :
print ( '{}正在卖第{}张火车票!' . format ( current_thread( ) . name, ticket) )
ticket -= 1
time. sleep( 1 )
else :
break
if __name__ == '__main__' :
t1 = Thread( target= sale_ticket, name= '1号窗口' )
t2 = Thread( target= sale_ticket, name= '2号窗口' )
t3 = Thread( target= sale_ticket, name= '3号窗口' )
t1. start( )
t2. start( )
t3. start( )
因为有锁的形式所以当时间大,运算量大的时候会出现不准的轻快,所以有锁的形式:
from threading import Thread, Lock
number = 0
def task ( lock) :
global number
lock. acquire( )
for i in range ( 100000 ) :
number += 1
lock. release( )
if __name__ == '__main__' :
lock = Lock( )
t1 = Thread( target= task, name= '1号窗口' , args= ( lock, ) )
t2 = Thread( target= task, name= '2号窗口' , args= ( lock, ) )
t3 = Thread( target= task, name= '3号窗口' , args= ( lock, ) )
t1. start( )
t2. start( )
t3. start( )
t1. join( )
t2. join( )
t3. join( )
print ( 'number:' , number)
** 锁:**
from threading import Lock
lock = Lock( )
lock. acquire( )
lock. release( )