Python--day9--进程/线程/协程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python--day9--进程/线程/协程相关的知识,希望对你有一定的参考价值。
介绍
学习记录 2016年12月29日 19:36:23
目录:
- 进程/线程基础概念
- GIL
- Join & Daemon
- 线程锁
- RLock递归锁
- 信号量
- Event
- Queques
进程
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
线程
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
GIL Global Interpreter Lock
直接调用 2个同时出现。并行
import threading
import time
def sayhi(num): # 定义每个线程要运行的函数
print("running on number:%s" % num)
time.sleep(3)
if __name__ == ‘__main__‘:
t1 = threading.Thread(target=sayhi, args=(1,)) # 生成一个线程实例
t2 = threading.Thread(target=sayhi, args=(2,)) # 生成另一个线程实例
t1.start() # 启动线程
t2.start() # 启动另一个线程
print(t1.getName()) # 获取线程名
print(t2.getName())
继承调用
import threading
import time
class MyThread(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num
def run(self): # 定义每个线程要运行的函数
print("running on number:%s" % self.num)
time.sleep(3)
if __name__ == ‘__main__‘:
t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()
多个线程调用 join
import threading
import time
def sayhi(num): # 定义每个线程要运行的函数
print("running on number:%s" % num)
time.sleep(3)
if __name__ == ‘__main__‘:
t_list = []
for i in range(10):
t = threading.Thread(target=sayhi, args=(i,)) # 生成一个线程实例
t.start()
t_list.append(t)
for i in t_list:
i.join() ##等待线程执行完毕
print(‘---------main----------‘)##第3个线程
Daemon
import time
import threading
def run(n):
print(‘[%s]------running----\n‘ % n)
time.sleep(2)
print(‘--done--‘)
def main():
for i in range(5):
t = threading.Thread(target=run, args=[i, ])
t.start()
print(‘starting thread‘, t.getName())
m = threading.Thread(target=main, args=[])
m.setDaemon(True) # 将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
m.start()
m.join(timeout=2)
print("---main thread done----")
线程锁(Mutex)
一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据
import time
import threading
def addNum():
global num # 在每个线程中都获取这个全局变量
print(‘--get num:‘, num)
time.sleep(1)
lock.acquire() # 修改数据前加锁
num -= 1 # 对此公共变量进行-1操作
lock.release() # 修改后释放
num = 100 # 设定一个共享变量
thread_list = []
lock = threading.Lock() # 生成全局锁
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list: # 等待所有线程执行完毕
t.join()
print(‘final num:‘, num)
RLock(递归锁)
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res = run1()
print(‘--------between run1 and run2-----‘)
res2 = run2()
lock.release()
print(res, res2)
if __name__ == ‘__main__‘:
num, num2 = 0, 0
lock = threading.RLock()
for i in range(10):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print(‘----all threads done---‘)
print(num, num2)
Semaphore信号量
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据
import threading, time
def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" % n)
semaphore.release()
if __name__ == ‘__main__‘:
num = 0
semaphore = threading.BoundedSemaphore(3) # 最多允许3个线程同时运行
for i in range(20):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1:
pass # print threading.active_count()
else:
print(‘----all threads done---‘)
print(num)
Events
通过Event来实现两个或多个线程间的交互
import threading,time
import random
def light():
if not event.isSet():
event.set() #wait就不阻塞 #绿灯状态
count = 0
while True:
if count < 10:
print(‘\033[42;1m--green light on---\033[0m‘)
elif count <13:
print(‘\033[43;1m--yellow light on---\033[0m‘)
elif count <20:
if event.isSet():
event.clear()
print(‘\033[41;1m--red light on---\033[0m‘)
else:
count = 0
event.set() #打开绿灯
time.sleep(1)
count +=1
def car(n):
while 1:
#time.sleep(random.randrange(10))
time.sleep(1)
if event.isSet(): #绿灯
print("car [%s] is running.." % n)
else:
print("car [%s] is waiting for the red light.." %n)
event.wait()
if __name__ == ‘__main__‘:
event = threading.Event()
Light = threading.Thread(target=light)
Light.start()
for i in range(3):
t = threading.Thread(target=car,args=(i,))
t.start()
多进程
from multiprocessing import Process
import os
def info(title):
print(title)
print(‘module name:‘, __name__)
print(‘parent process:‘, os.getppid())
print(‘process id:‘, os.getpid())
print("\n\n")
def f(name):
info(‘\033[31;1mfunction f\033[0m‘)
print(‘hello‘, name)
if __name__ == ‘__main__‘:
info(‘\033[32;1mmain process line\033[0m‘)
p = Process(target=f, args=(‘bob‘,))
p.start()
p.join()
Queues
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, ‘hello‘])
if __name__ == ‘__main__‘:
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, ‘hello‘]"
p.join()
Pipes 管道 不常用
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, ‘hello‘])
conn.close()
if __name__ == ‘__main__‘:
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, ‘hello‘]"
p.join()
Managers
from multiprocessing import Process, Manager
def f(d, l):
d[1] = ‘1‘
d[‘2‘] = 2
d[0.25] = None
l.append(1)
print(l)
if __name__ == ‘__main__‘:
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)
进程同步
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print(‘hello world‘, i)
finally:
l.release()
if __name__ == ‘__main__‘:
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
进程池
from multiprocessing import Process, Pool,freeze_support
import time
def Foo(i):
time.sleep(2)
return i + 100
def Bar(arg):
print(‘-->exec done:‘, arg)
if __name__ == ‘__main__‘:
freeze_support()
pool = Pool(5)
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar)
# pool.apply(func=Foo, args=(i,))
print(‘end‘)
pool.close()
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
paramiko模块
本文出自 “何全” 博客,请务必保留此出处http://hequan.blog.51cto.com/5701886/1887449
以上是关于Python--day9--进程/线程/协程的主要内容,如果未能解决你的问题,请参考以下文章