博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python--进程与线程
阅读量:5153 次
发布时间:2019-06-13

本文共 5613 字,大约阅读时间需要 18 分钟。

一,回顾操作系统的概念

 操作系统位于底层硬件与应用软件之间的一层

 工作方式:向下管理软件,向上提供接口

二,进程线程的概念

  进程是一个资源单位,线程是一个最小的执行单位

    一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程

三,并行与并发

并行:

    就是有多个进程可以同时运行的叫做并行
并发:
    就是在一个处理器的情况下,切换执行,叫做并发
python无法实现并行处理,因为全局解释器锁gil导致同一时刻同一进程
只能有一个线程被运行。
    GIL全局解释器锁
    但是不影响Python开多进程
多线程代码示例
    

import threadingimport time'''程序在运行是有一个主线程,当程序开启多线程的时候,主线程依旧会执行,主线程执行到最后时,并没有结束,而是在等待子线程的结束后主线程结束'''def misc():    print("听歌")    time.sleep(3)    print("听歌结束")def xieboke():    print("写博客")    time.sleep(5)    print("写博客结束")#开启线程t1=threading.Thread(target=misc)#t1,t2是一个线程对象t2=threading.Thread(target=xieboke)t1.start()t2.start()print("主线程")

 

#开启多线程的另一种方式

import threadingimport timeclass MyThread(threading.Thread):    '''    用类的继承,继承线程的方法开启线程    '''    def __init__(self,num):    '''    继承父类的__init__方法    '''        threading.Thread.__init__(self)        self.num=num    def run(self):        print("running on mythread:%s"%self.num)        time.sleep(3)        print("end%s"%self.num)t1=MyThread(10)t2=MyThread(20)t1.start()t2.start()print("主线程")

 

jion的使用
    t.jion方法会阻塞主进程的运行,但不会影响其他线程的运行
setDaemon方法
    -守护线程
    当某个线程设置为守护线程的时候,它会随着主线程的结束而结束
    t.setDaemon(True)
    
线程对象下的几个方法:
        -isAlive()检测线程是否活动,返回值是布尔值
        -getName():返回线程名
        -setName():设置线程名称
        
threading模块提供的一些方法:
    threading.currentTread():返回当前线程变量
    threading.enumerate():返回一个包含正在运行的线程的list。
    threading.activeCount():返回正在运行的线程数量
    
Python对于计算密集型运行比较慢,效率低;对于IO密集型效率有明显提高
Python多线程
    互斥锁:
        互斥锁的意义就是在保护锁内代码同一时间只有一个线程在使用
        直到代码执行完成,解锁后其他线程才能执行所内代码。
    使用格式:
        -lock=threading.Lock()创建一把锁的对象
        lock.acquire()#加锁
        ....需要保护的执行语句
        lock.release()#解锁
    
    死锁与递归锁    
    代码示例:
      

      import threading        import time        muteA=threading.Lock()        muteB=threading.Lock()        class MyThread(threading.Thread):            def __init__(self):                threading.Thread.__init__(self)            def run(self):                self.func1()                self.func2()            def func1(self):                muteA.acquire()                print("锁A执行内容",MyThread.getName(self))                muteB.acquire()                print("锁B执行内容",MyThread.getName(self))                muteB.release()                muteA.release()            def func2(self):                muteB.acquire()                print("第二个函数的锁B",MyThread.getName(self))                muteA.acquire()                print("第二个函数的锁A",MyThread.getName(self))                muteA.release()                muteB.release()        if __name__=="__main__":            for i in range(10):                my_thread=MyThread()                my_thread.start()

 

        
    形成死锁的原因在于当线程1在第二个函数中拿到锁B向下执行需要锁A的时候,线程2在函数1中
    已经拿到的锁A,在等待线程1释放B。两个线程都没有释放另一个线程需要的锁,所以就形成了死锁。
    
    
    递归锁的应用
    递归锁未避免死锁的产生,在锁内实行一个引用计数,当有一把使用是计速器加一,释放后,去除计数
    到代码在执行锁内代码时,如果有其他线程抢锁,计数如果为零,线程可以拿到锁,大于零,拒绝线程拿锁
    这样就能避免锁的重复,也就不会产生死锁
    代码示例:    
    import threading
        import time
        Rlock=threading.Rlock()
        class MyThread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)
            def run(self):
                self.func1()
                self.func2()
            def func1(self):
                Rlock.acquire()
                print("锁A执行内容",MyThread.getName(self))
                Rlock.acquire()
                print("锁B执行内容",MyThread.getName(self))
                Rlock.release()
                Rlock.release()
            def func2(self):
                Rlock.acquire()
                print("第二个函数的锁B",MyThread.getName(self))
                Rlock.acquire()
                print("第二个函数的锁A",MyThread.getName(self))
                Rlock.release()
                Rlock.release()
        if __name__=="__main__":
            for i in range(10):
                my_thread=MyThread()
                my_thread.start()
                
event方法使用:
    event方法可以让两个线程之间通信,当一个线程需要另一个线程准备数据的时候,
    event.wait(),阻塞程序的运行,直到另一个线程将数据准备完成后,使用event.set()
    返回一个true值,event.wait()接受到该值之后,线程开始运行。wait方法后可以接一个超时
    时间参数,规定在一定时间内阻塞,超时后运行。
    
    import threading
    import time
    import logging
    logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)
    def worker(event):
        logging.debug('Waiting for redis ready...')
        while not event.isSet():
            logging.debug("wait.......")
            event.wait(3)   # if flag=False阻塞,等待flag=true继续执行
        logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())
        time.sleep(1)
    def main():
        readis_ready = threading.Event()  #  flag=False创建一个event对象
        t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')
        t1.start()
        t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')
        t2.start()
        logging.debug('first of all, check redis server, make sure it is OK, and then trigger the redis ready event')
        time.sleep(6) # simulate the check progress
        readis_ready.set()  # flag=Ture
        
    if __name__=="__main__":
        main()
    
进程multprocessing模块
    multprocessing模块与threading模块使用同一套api,使用方法调用方法与threading模块一样
    
    代码示例:
    from multiprocessing import Process
    import time
    def f(name):
        print("hello",name,time.ctime())
        time.sleep(1)
    if __name__=="__main__":
        p_list=[]
        for i in range(3):
            p=Process(target=f,args=("alvin:%s"%i,))
            p_list.append(p)
            p.start()
    
    
协程的应用:
    协程是单线程的,不能切换。因为协程对IO操作的判断由自己控制
    import time
    #  可以实现并发
    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] ←← Consuming %s...' % n)
            time.sleep(1)
            r = '200 OK'
    def produce(c):
        next(c)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] →→ Producing %s...' % n)
            cr = c.send(n)
            print('[PRODUCER] Consumer return: %s' % cr)
        c.close()
    if __name__=='__main__':
        c = consumer()
        produce(c)
    
gevent模块的使用:
    from gevent import monkey
    monkey.patch_all()
    import gevent
    from urllib import request
    import time
    def f(url):
        print('GET: %s' % url)
        resp = request.urlopen(url)
        data = resp.read()
        print('%d bytes received from %s.' % (len(data), url))
    start=time.time()
     gevent.joinall([
             gevent.spawn(f, 'https://itk.org/'),
             gevent.spawn(f, 'https://www.github.com/'),
             gevent.spawn(f, 'https://zhihu.com/'),
     ])
    #f('https://itk.org/')
    #f('https://www.github.com/')
    #f('https://zhihu.com/')
    print(time.time()-start)  

转载于:https://www.cnblogs.com/lzh1118/p/7430014.html

你可能感兴趣的文章
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
C++有关 const & 内敛 & 友元&静态成员那些事
查看>>
函数积累
查看>>
Swift 入门之简单语法(六)
查看>>
〖Python〗-- IO多路复用
查看>>
栈(括号匹配)
查看>>
Java学习 · 初识 面向对象深入一
查看>>
源代码如何管理
查看>>
vue怎么将一个组件引入另一个组件?
查看>>
bzoj1040: [ZJOI2008]骑士
查看>>
LeetCode 74. Search a 2D Matrix(搜索二维矩阵)
查看>>
利用SignalR来同步更新Winfrom
查看>>
反射机制
查看>>
CocoaPod
查看>>
BZOJ 1251: 序列终结者 [splay]
查看>>
5G边缘网络虚拟化的利器:vCPE和SD-WAN
查看>>
MATLAB基础入门笔记
查看>>
【UVA】434-Matty&#39;s Blocks
查看>>
Android开发技术周报 Issue#80
查看>>
hadoop2.2.0+hive-0.10.0完全分布式安装方法
查看>>