吴先生不爱吃辣

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1,进程和线程的区别

打开一个程序相当于一个进程,而程序中的读取数据,传输数据等不同的功能相当于不同的线程。线程没有利用到多核的优势,一个进程内的所有线程的内存是共享的,但是开启线程不会消耗太大的资源;进程中的内存都是独立的,每次开启一个进程都需要申请新的内存空间。

2,开启进程(线程)的两种方法

进程:

#使用方法来来使用多进程
import time
import random
from multiprocessing import Process
def piao(name):
    print('%s piaoing' %name)
    time.sleep(random.randrange(1,5))
    print('%s piao end' %name)
if __name__ == '__main__':
    #实例化得到四个对象
    p1=Process(target=piao,args=('egon',)) #必须加,号
    p2=Process(target=piao,args=('alex',))
    p3=Process(target=piao,args=('wupeqi',))
    p4=Process(target=piao,args=('yuanhao',))
    #调用对象下的方法,开启四个进程
    p1.start()
    p2.start()
    p3.start()
    p4.start()
    print('')
#使用类来使用多进程
import time
import random
from multiprocessing import Process
class Piao(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print('%s piaoing' %self.name)
time.sleep(random.randrange(1,5))
print('%s piao end' %self.name)
if __name__ == '__main__':
#实例化得到四个对象
p1=Piao('egon')
p2=Piao('alex')
p3=Piao('wupeiqi')
p4=Piao('yuanhao')
#调用对象下的方法,开启四个进程
p1.start() #start会自动调用run
p2.start()
p3.start()
p4.start()
print('主')

 线程

因为GIL的存在,所以在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势
#线程中使用方法来使用多线程
from threading import Thread
import time
def sayhi(name):
time.sleep(2)
print('%s say hello' %name)
if __name__ == '__main__':
t=Thread(target=sayhi,args=('egon',))
t.start()
print('主线程')
#线程中使用类来使用多线程
from threading import Thread
import time
class Sayhi(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        time.sleep(2)
        print('%s say hello' % self.name)
if __name__ == '__main__':
    t = Sayhi('egon')
    t.start()
    print('主线程')

3,进程池和线程池

#进程池使用pool.apply加入进程池是并行的,没有并行的效果
from multiprocessing import Process, Pool
# 从multiprocessing导入pool

import time, os


def Foo(i):
    time.sleep(2)
    print("in process", os.getpid())  # 打印进程id
    return i + 100


def Bar(arg):
    print('-->exec done:', arg)


if __name__ == '__main__':  ##这行代码用途是如果主动执行该代码的.py文件,则该代码下面的代码可以被执行;如果该.py模块被导入到其他模块中,从其他模块执行该.py模块,则该行下面的代码不会被执行。  有些时候可以用这种方式用于测试,在该行代码下面写一些测试代码。。
    pool = Pool(5)  # 同时只能放入5个进程

    for i in range(10):  # 创建10个进程,但是因为pool的限制,只有放入进程池中的5个进程才会被执行(),其他的被挂起了,如果进程池中其中有两个进程执行完了,就会补进2个进程进去。
        # pool.apply_async(func=Foo, args=(i,), callback=Bar)
        pool.apply(func=Foo, args=(i,))  # pool.apply用来将进程放入pool

    print('end')  # 执行完毕
    pool.close()  # 允许pool中的进程关闭(close必须在join前面,可以理解close相当于一个开关吧)
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
#pool.apply_async  加入进程池的方式是并行
from
multiprocessing import Process, Pool import time, os

def Foo(i): time.sleep(2) print("in process", os.getpid()) return i + 100 def Bar(arg): print('-->exec done:', arg) if __name__ == '__main__': pool = Pool(5) for i in range(10): pool.apply_async(func=Foo, args=(i,)) ## 使用pool.apply_async就可以并行了 print('end') pool.close() pool.join()
#并行运行并且使用回调函数
from multiprocessing import Process, Pool
import time, os


def Foo(i):
    time.sleep(2)
    print("in process", os.getpid())
    return i + 100


def Bar(arg):
    print('-->exec done:', arg, os.getpid())


if __name__ == '__main__':
    pool = Pool(5)

    print("主进程:", os.getpid())  # 打印主进程id
    for i in range(10):
        pool.apply_async(func=Foo, args=(i,), callback=Bar)
        ##callback叫做回调,就是当执行完了func=Foo后,才会执行callback=Bar(每个进程执行完了后都会执行回调)。
        ## 回调可以用于当执行完代码后做一些后续操作,比如查看完命令后,通过回调进行备份;或者执行完什么动作后,做个日志等。
        ## 备份、写日志等在子进程中也可以执行,但是为什么要用回调呢! 这是因为如果用子进程,有10个子进程就得连接数据库十次,而使用回调的话是用主进程连接数据库,所以只连接一次就可以了,这样写能大大提高运行效率。
        ##通过主进程建立数据库的连接的话,因为在同一个进程中只能在数据库建立一次连接,所以即使是多次被子进程回调,也不会重复建立连接的,因为数据库会限制同一个进程最大连接数,这都是有数据库设置的。

    print('end')
    pool.close()
    pool.join()

 4、协程

线程和协程的区别:线程的切换时操作系统执行的,分两种情况1是该任务发生了阻塞,任务运行时间到了或者一个优先级更高的任务代替了它。

而协程是用户程序自己控制调度的。

from datetime import datetime
import asyncio

async def add(n):
    print(datetime.now().strftime('%H:%M:%S.%f'))
    count = 0
    for i in range(n):
        count += i
    print(datetime.now().strftime('%H:%M:%S.%f'))
    return count

async def fun(n):
    res = await add(n)
    print(f'res = {res}')

loop = asyncio.get_event_loop()
tasks = [fun(20000000), fun(30000000)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
使用asyncio开启协程
import time

import queue


def consumer(name):
    print("--->starting eating baozi...")
    while True:
        new_baozi = yield
        print("[%s] is eating baozi %s" % (name, new_baozi))
        # time.sleep(5)


def producer():
    r = con.__next__()
    r = con2.__next__()
    n = 0
    while n < 5:
        n += 1
        con.send(n)
        con2.send(n)
        print("\033[32;1m[producer]\033[0m is making baozi %s" % n)


if __name__ == '__main__':
    con = consumer("c1")
    con2 = consumer("c2")
    p = producer()
使用yield开启携程
    import gevent
    def eat(name):
        print('%s eat 1' %name)
        gevent.sleep(2)
        print('%s eat 2' %name)
    def play(name):
        print('%s play 1' %name)
        gevent.sleep(1)
        print('%s play 2' %name)
    g1=gevent.spawn(eat,'egon')
    g2=gevent.spawn(play,name='egon')
    g1.join()
    g2.join()
    #或者gevent.joinall([g1,g2])
    print('')
使用gevent实现协程

 

posted on 2020-04-07 17:25  吴先生不爱吃辣  阅读(387)  评论(0编辑  收藏  举报