shanau2

导航

 

周三 多线程 (非常重要)() 多线程互斥锁 (重要)() 守护线程 (一般)() 信号量 一般() 生产者消费者+守护进程 一般(**)

周四 GIL锁 线程池 进程池

周五 协程

多线程

多线程也是用于提高程序的效率

多进程
    核心是多道技术       
    本质上就是切换保存状态
    当程序IO操作较多 可以提高程序效率
    
多线程
什么是线程
    程序的执行线路
    相当于一条流水线,其包含了程序的具体执行步骤
    如果我们把操作系统比作一个工厂,进程就是车间,线程就是流水线
    
线程和进程的关系
    进程中包含了运行该程序所需要的所有资源
    *进程是一个资源单位,线程是cpu的最小执行单位*
    每一个进程一旦被创建,就默认开启了一条线程,我们把这个线程称之为主线程
    一个进程可以包含多个线程
    进程包含线程,而 线程依赖进程
    
为什么使用线程
    是为了提高程序效率
    为何不用多进程提高效率? 是因为进程对操作系统的资源耗费非常高
        
线程是如何提高效率的?
    可以使cpu在一个进程内切换,从而提高cpu的占用率
    
    
什么情况下应该开启多线程
    当程序中遇到IO操作的时候
什么情况下不应该开启多线程
    当程序中是纯计算任务的时候,也无法提高效率
    
进程和线程的区别
    1.进程对于操作系统的资源耗费非常高,而线程相反非常低(比进程低10_100倍)
    2.在同一个进程中,多个线程之间的资源是共享的
        
如何使用    
    两种开启线程的方式
    1.实例化Tread类
    2.继承Tread类 覆盖run方法

# 开启线程的第一种方式
from threading import Thread
from multiprocessing import Process

def task():
    print("threading running!")

t1 = Thread(target=task)
t1.start()
print("over")



# 第二种方式
class MyThread(Thread):
    def run(self):
        print("子线程 running....")
MyThread().start()
print("over2")

对比进程启动时间

from threading import Thread      
import time                       
                             
# class MyThread(Thread):         
#     def run(self):              
#         # print("子进程run.....")  
#        pass                     
#                                 
# if __name__ == '__main__':      
#                                 
#     ts = []                     
#     start = time.time()         
#     for i in range(100):        
#                                 
#         t1 = MyThread()         
#         t1.start()              
#         ts.append(t1)           
#                                 
#     for t in ts:                
#         t.join()                
#                                 
#     print(time.time()-start)    
#     print("over")               


from multiprocessing import Process                   
import time                                           
def task():                                           
    pass                                              

    # print("子进程run...")                              

if __name__ == '__main__':                            
    p   s = []                                           
    start = time.time()                               
    for i in range(100):                              
        p = Process(target=task)                      

        p.start()                                     
        ps.append(p)                                  

    for p in ps:                                      
        p.join()                                      

    print(time.time()-start)                          
    print("over")

进程间资源共享

from threading import Thread          
a = 100                               
                                      
def task():                           
    global a                          
    a = 0                             
                                      
if __name__ == '__main__':            
    t = Thread(target=task)           
    t.start()                         
                                      
    print(a)

守护线程

守护线程会在所有非守护线程结束后结束
    如果把皇后设置为守护线程,那么皇后线程会在太子和皇帝都死亡后死亡

进程 守护进程会在被守护进程死亡跟着死亡
同一个进程 可以有多个守护线程

"""
    守护线程
    守护线程会在所有非守护线程结束后结束
        三个线程 分贝 皇帝 太子 和皇后
        如果把皇后设置为守护线程 那么皇后线程会在 太子和皇帝都死亡后死亡
    当所有非线程结束后 守护线程也跟着结束了


    进程 守护进程会在被守护进程死亡跟着死亡
    同一个进程 可以有多个守护线程

"""

from threading import Thread

#
# import time
#
# def task():
#     print("sub thread run....")
#     time.sleep(3)
#     print("sub thread over....")
#
# t = Thread(target=task)
# t.setDaemon(True)
# t.start()
#
#
# t = Thread(target=task)
# t.setDaemon(True)
# t.start()
#
# print("over!")
from threading import Thread
import time

def task():
    print("子线程运行。。。")
    time.sleep(1)
    print("子线程结束。。。")
t = Thread(target=task)
t.setDaemon(True)

t.start()
# time.sleep(0.1)
print("over")

线程常用方法

from threading import Thread,current_thread,enumerate,active_count

import os

def task():
    print("running..")
    # print(os.getpid())
    # print(current_thread())
    print(active_count())

t1 = Thread(target=task)
t1.start()
# print(t1.is_alive())
# print(t1.isAlive())
# print(t1.getName())

# 获取所有线程对象列表
print(enumerate())
# 获取当前线程对象
print(current_thread())
# 获取当前正在运行的线程个数
print(active_count())

# t2 = Thread(target=task)
# t2.start()

什么时候用锁

当多个进程或多个线程需要同时修改同一份数据时,可以加锁

import time
from threading import Thread,Lock

lock =Lock()

a = 100

def task():
    lock.acquire()
    global a
    temp = a - 1
    time.sleep(0.01)
    a = temp
    lock.release()

ts = []
for i in range(100):
    t = Thread(target=task)
    t.start()
    ts.append(t)

for t in ts:
    t.join()


print(a)

信号量

其实也是一种锁,特点是可以设置一个数据可以被几个线程(进程)共享

与普通锁的区别
    普通锁一旦加锁,则意味着,这个数据在同一时间只能被一个线程使用
    信号量可以让这个数据在同一时间被多个线程使用
使用场景,可以限制一个数据被同时访问的次数,保证程序正常运行
    

from threading import Semaphore,Thread,current_thread
import time,random

sem = Semaphore(3)

def task():
    sem.acquire()
    print("%s run..." % current_thread())
    time.sleep(3)
    sem.release()


for i in range(10):
    t = Thread(target=task)
    t.start()

守护进程在生产者消费者模型中的使用

"""
    生产者与消费者模型


    吃热狗 与  做热狗
"""
import time,random
from multiprocessing import Process,JoinableQueue
def eat_hotdog(name,q):
    while True:
        res = q.get()
        print("%s吃了%s" % (name,res))
        time.sleep(random.randint(1,2))
        q.task_done() #记录已经被处理的数据的数量

def make_hotdog(name,q):
    for i in range(1,6):
        time.sleep(random.randint(1, 2))
        print("%s生产了第%s个热狗" % (name,i))
        res = "%s的%s个热狗" % (name,i)
        q.put(res)
    # q.put(None)

if __name__ == '__main__':
    q = JoinableQueue()
    #生产者1
    c1 = Process(target=make_hotdog,args=("万达热狗店",q))
    c1.start()

    #生产者2
    c2 = Process(target=make_hotdog, args=("老男孩热狗店", q))
    c2.start()

    # 消费者
    p2 = Process(target=eat_hotdog,args=("思聪",q))

    p2.start()


    # 首先保证生产者全部产完成
    c1.join()
    c2.join()

    # 保证队列中的数据全部被处理了
    q.join() # 明确生产方已经不会再生成数据了
posted on 2019-01-02 16:28  shanau2  阅读(172)  评论(0编辑  收藏  举报