Python--day9--进程/线程/协程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python--day9--进程/线程/协程相关的知识,希望对你有一定的参考价值。

 介绍

学习记录 2016年12月29日 19:36:23

目录:
  1. 进程/线程基础概念
  2. GIL
  3. Join  &  Daemon
  4. 线程锁
  5. RLock递归锁
  6. 信号量
  7. Event
  8. 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--进程/线程/协程的主要内容,如果未能解决你的问题,请参考以下文章

python day9 学习整理

简述python进程,线程和协程的区别及应用场景

初识进程 线程 协程:协程

进程线程协程

进程线程协程的区别

进程线程轻量级进程协程和go中的Goroutine