• python day9


    本节内容

    进程与线程

    1.进程:

    程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。

    在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。

    进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:

    • 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。

    • 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

    2.线程:

    线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

    Python threading模块

    线程有2种调用方式,如下:

    直接调用

    # 直接调用
    import time
    import threading
    def run(name):
        print('%s线程执行.....'%name)
        time.sleep(3)
        pass
    
    t1 =threading.Thread(target=run,args=('A',))
    t2 =threading.Thread(target=run,args=('B',))
    t1.start()
    t2.start()
    View Code

    继承调用

    # 继承式
    import time
    import threading
    
    class MyThread(threading.Thread):
         def __init__(self,name):
             super(MyThread,self).__init__()
             self.name=name
             pass
    
         def run(self):
    
            print("running is thread %s"%self.name)
            time.sleep(3)
            pass
    
    
    
    t1=MyThread('C')
    t2=MyThread('D')
    t1.start()
    t2.start()
    View Code

    join:等待线程终止。(线程的合并)

    import time
    import threading
    
    class MyThread(threading.Thread):
         def __init__(self,name):
             super(MyThread,self).__init__()
             self.name=name
             pass
    
         def run(self):
    
            print("running is thread %s"%self.name)
            time.sleep(3)
            pass
    
    
    
    t1=MyThread('C')
    
    t2=MyThread('D')
    t1.start()#等待t1线程执行完毕在执行t2线程
    t1.join()
    t2.start()
    View Code

    Daemon:设置线程为守护线程

    守护线程是:辅助线程,当一个线程为另一个线程的守护线程时,那么如果另一个线程退出,那么守护线程也会退出,在守护线程中开启的线程也会同时退出。

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/6 23:44
    # software: PyCharm
    
    # 守护线程
    import time
    import threading
    class MyThread(threading.Thread):
        def __init__(self, name):
            super(MyThread, self).__init__()
            self.name = name
            pass
    
        def run(self):
            print("running is thread %s" % self.name)
            time.sleep(3)
            pass
    
    
    t1 = MyThread('C')
    
    t2 = MyThread('D')
    t1.setDaemon(True)#设置线程为守护线程。
    t2.setDaemon(True)
    t1.start()
    t2.start()
    
    
    print('mian 主线程执行完毕')
    View Code

    线程锁

       线程锁指的是:我们多线程在同时修改一个数据时,每个线程都会拿到同一份数据,那么修改完后数据的结果就会不正确了。

    import threading
    import time
    
    
    num=0
    def run(n):
    
       global num
       if n=='A':
        time.sleep(2)
        num+=1
        print("num", num)
    
       else:
           num+=1
    
           print("num", num)
    pass
    
    
    
    
    t1 = threading.Thread(target=run,args='A')
    t2=threading.Thread(target=run,args='B')
    
    t1.start()
    t2.start()
    View Code

    加锁后的代码:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/7 13:34
    # software: PyCharm
    
    import threading
    import time
    # 获取一个锁的实例
    lock =threading.Lock()
    num=0
    def run(n):
    
       global num
       lock.acquire()#加锁
       if n=='A':
        print("A",num)#线程A获取的num的值
        time.sleep(2)
    
        num+=1
        print("A修改后num", num)
        lock.release()#释放锁
    
       else:
           print("B:",num) #线程B获取的num的值
           num+=1
    
           print("B修改后num", num)
           lock.release()
    pass
    
    
    
    
    t1 = threading.Thread(target=run,args='A')
    t2=threading.Thread(target=run,args='B')
    
    t1.start()
    t2.start()
    View Code

    注意:在python3上有锁没锁,代码结果都是正确的,可能是python3自动加了锁。

    递归锁:

    我们可能在使用线程锁的时候,可能出现锁中套者锁,那么这个时候就可能出现,线程退不出来。

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/7 14:33
    # software: PyCharm
    
    
    # 递归锁
    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)
    
    
    
    num,num2 = 0,0
    lock = threading.Lock()
    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)
    View Code

    使用递归锁

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/7 14:33
    # software: PyCharm
    
    
    # 递归锁
    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)
    
    
    
    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)
    View Code

    Semaphore(信号量)

    互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据。

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/7 14:42
    # software: PyCharm
    
    import threading,time
    
    def run(n):
        semaphore.acquire()
        global num
        num+=1
        time.sleep(1)
    
        print("run the thread: %s" %n,num,'
    ')
        semaphore.release()
    
    if __name__ == '__main__':
    
        num= 0
        semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
        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)
    View Code

    Events

    Event(事件)是最简单的线程通信机制之一:一个线程通知事件,其他线程等待事件。Event内置了一个初始为False的标志,当调用set()时设为True,调用clear()时重置为 False。wait()将阻塞线程至等待阻塞状态。

    isSet(): 当内置标志为True时返回True。 
      set(): 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态。 
      clear(): 将标志设为False。 
      wait([timeout]): 如果标志为True将立即返回,否则阻塞线程至等待阻塞状态,等待其他线程调用set()。

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/7 16:26
    # software: PyCharm
    
    # 红绿等
    import threading
    import time
    
    event=threading.Event()
    
    def run():
        count=0;
        while True:
            if count>5 and count<10:
                event.clear()
                print('这是红灯请等待')
            elif count>10:
                event.set()
                count=0
            else:
                print('这是绿灯,请通行')
    
            time.sleep(1)
            count+=1
        pass
    
    def car(name):
    
        while True:
            if event.is_set():
                print('请 赶紧通行',name)
            else:
                print("请等待红灯")
                event.wait()
        pass
    
    h=threading.Thread(target=run,)
    c=threading.Thread(target=car,args=('奔驰',))
    c1=threading.Thread(target=car,args=('宝马',))
    h.start()
    c.start()
    c1.start()
    View Code

    队列:

    queue

    queue是用户多线程编程中的,线程之间的通信。

    python中有3种队列:

    class queue.Queue(maxsize=0) #先入先出
    class queue.LifoQueue(maxsize=0) #last in fisrt out 
    class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列
    queue常用的方法:
    将一个值放入队列中 put方法
    将一个值从队列中取出 get方法

    q.qsize() 返回队列的大小
    q.empty() 如果队列为空,返回True,反之False
    q.full() 如果队列满了,返回True,反之False
    q.full 与 maxsize 大小对应
    q.get([block[, timeout]]) 获取队列,timeout等待时间
    q.get_nowait() 相当q.get(False)
    非阻塞 q.put(item) 写入队列,timeout等待时间
    q.put_nowait(item) 相当q.put(item, False)
    q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号

    q.join() 实际上意味着等到队列为空,再执行别的操作

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:Dragon war
    # datetime:2018/9/10 14:16
    # software: PyCharm
    
    # 队列 queue
    
    # 队列使用queue模块
    
    import queue
    
    
    # 创建队列:先进先出
    q=queue.Queue()
    # 往队列中添加
    q.put(1)
    q.put(2)
    
    # 队列大小
    
    print(q.qsize())
    
    # 从队列中取值
    
    print(q.get())
    print(q.get())
    # 如果队列中没有值了,那么再调用get方法,将会阻塞
    
    print(q.get())
    while not  q.empty():
    
        print(q.get())
    
    qe=queue.LifoQueue()  #先进后出
    
    for i in range(5):
        qe.put(i)
        pass
    
    # 取值
    while not  qe.empty():
    
        print(qe.get())
    
    
    # 优先级队列
    
    qq =queue.PriorityQueue()
    # 添加
    qq.put(10,"aaa")
    qq.put(6,"bbbb")
    qq.put(12,"cccc")
    qq.put(3,"ddddd")
    
    # 取值
    while not qq.empty():
    
        print(qq.get())
    
        pass
    View Code
  • 相关阅读:
    Elasticsearch 索引操作
    windows curl命令
    Elasticsearch简介
    ElasticSearch插件安装
    SignalR实时聊天功能
    原来现在很多人都用SignalR来实现Chat Room
    设计模式(六)(Command Pattern)命令模式
    FtpWebRequest FTP异步下载、异步上传文件
    FTP规范
    oracle组建:ODAC112021Xcopy_x64,在开发机上,不用安装oracle的客户端等开发
  • 原文地址:https://www.cnblogs.com/wuzhilong/p/9599607.html
Copyright © 2020-2023  润新知