Python--进程与线程

一,回顾操做系统的概念python

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

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

二,进程线程的概念redis

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

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

三,并行与并发并发

并行:
    就是有多个进程能够同时运行的叫作并行
并发:
    就是在一个处理器的状况下,切换执行,叫作并发

python没法实现并行处理,由于全局解释器锁gil致使同一时刻同一进程
只能有一个线程被运行。

    GIL全局解释器锁
    可是不影响Python开多进程

多线程代码示例
    app

import threading
import 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 threading
import time
class 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()#解锁
    
    死锁与递归锁    
    代码示例:
      ui

       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)  

相关文章
相关标签/搜索