三.python 高级内容 ------线程

基本概念:
    线程:进程中的每个子任务,不能独立存在,CPU执行的最小  单位
    进程:独立的所有子任务的集合
    线程,进程:目的都是想同时完成任务

特点:
    进程的特点:独立(内存独立,cpu使用独立)启动进程开销大(速率低),
    进程之间很难共享数据,和数据通信,数据安全高。
  线程的特点:依赖进程(内存共享,CPU使用独立)启动开销小,
    线程之间共享数据容易,方便通信,线程不安全。

Thread类提供了以下方法:
run(): 用以执行线程活动的方法。
start():启动线程活动使线程达到一个就绪状态
join([time]):强制调用某个线程进入执行状态,本线程礼让CPU资源,
进入阻塞,休眠状态,直至某个线程退出/抛异常/超时 本线程才进入
就绪状态  等待至线程中止。这阻塞调用线程直至线程的join() 方法
被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。

getName(): 返回线程名。

setName(): 设置线程名。

import threading

print(x for x in range(9))
thread=threading.current_thread()
thread.setName('主线程')
print('thread name:',thread.getName())
new_th=threading.enumerate()
print('正在运行的线程:',new_th)
print('正在运行的线程个数:',new_th)


 线程类:
 第一种方式   类实现
'''
 类方式
 1.继承threading.Thread
 2.写构造方法,且必须调用父类的构造方法
 3.重写父类的run方法,会在start之后自动调
 4.实现开始方法,如果重写了start()方法,一定要调用父类的start()
 需要调用start()方法才可以执
'''

import threading,time
class Mythread(threading.Thread):
    def __init__(self):
       threading.Thread.__init__(self)
       print('Mythread __init__()')

    def run(self):
        for i in range(10):
            print(self.getName(), i)
            time.sleep(0.1)

t1=Mythread()
t2=Mythread()
t1.start()
t2.start()
for i in range(10):
    print(threading.current_thread().getName(), i)
    time.sleep(0.1
    if i==5:
        # 那个线程调用 那个线程停止
        #  0.2 等待时常 就开始恢复就绪状态
         t1.join(1)
new_th=threading.enumerate()
print('正在运行的线程:',new_th)
# input()


 第二种方式:函数实现   资源共享
  '''
  注意:函数实现方式:线程必须依赖函数实现,不能单独运行。
  当函数结束,线程结束。所以如果想让线程一直运行,就要想办
  法让程序不结束,比如在程序最后加一个input(),或死循环。

  当多个线程同时进行任务时,为了保证不会有多个线程同时对同
  一个数据进行操作造成不可预料的后果,所以有了锁的概念,
  我们通过锁来使多线程任务更加安全。
  '''

import threading,time
nums=100
#资源共享
def something(x):
    for i in range(1,x):
        global nums
        nums=nums+1
        print(nums)
        time.sleep(0.2)
threading._start_new_thread(something,(11,))
threading._start_new_thread(something,(11,))
input()


 练习1:抢票   锁
 '''
 由于并发的问题,需要加锁:
 锁当然有锁定和未锁定两种状态,当一个线程要访问共享数据时,
 必须要先获得锁定,如果已经有别的线程获得锁定,那么就进入暂
 停状态,等别的线程把锁释放后,再进行操作。

 Condition:更精确的控制锁,提供了四个方法:
 上锁(acquire()),等待(wait()),解锁(release()),
 唤醒(notify(),notify_all())
 '''
import threading,time
nums=50
count=0
lock = threading.Lock()                 # 创建一把锁
Cond = threading.Condition(lock=lock)   # 管理一把锁

class qiangpiao(threading.Thread):
    def __init__(self,name):
        threading.Thread.__init__(self)
        self.setName(name)
    def run(self):
        global nums,count
        while True:
            Cond.acquire()  # 当哪个线程获得了资源 就加上锁
            if nums==0:
                print('没票了')
                return
            nums=nums-1
            count=count+1
            print('{0}抢到了{1}剩余{2}'.format(self.getName(),count,nums))
            time.sleep(0.2)
            Cond.release() # 当哪个线程完成了处理 就解开锁
if __name__=='__main__':
    huangniu=qiangpiao('黄牛')
    shouji=qiangpiao('手机')
    chuangkou=qiangpiao('窗口')

    huangniu.start()
    shouji.start()
    chuangkou.start()
    # 多线程共享数据

 练习2:蒸馒头 消费者生产者
 '''
 一个伙夫蒸馒头(生产者,售票),要求蒸够30个,等待,并唤醒吃馒头的人
 三个吃货吃馒头(消费者,买票),要求同时吃,当任何一个人发现没馒头了,
 唤醒伙夫。
 
 
 生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用List数组队列,
 数据类型只需要定义一个简单的类就好。关键是如何处理多线程之间的协作。
 这其实也是多线程通信的一个范例。
 在这个模型中,最关键就是内存缓冲区为空的时候消费者必须等待,
 而内存缓冲区满的时候,生产者必须等待。其他时候可以是个动态平衡。
 值得注意的是多线程对临界区资源的操作时候必须保证在读写中只能存在
 一个线程,所以需要设计锁的策略。
 '''

import threading,time
zhenglong=[]    # 蒸笼
# 创建2把锁,一把蒸馒头的锁,由伙夫掌管
# 另外一把吃馒头色锁,由 吃货 掌管
zheng_lock = threading.Lock()
zheng_Cond = threading.Condition(lock=zheng_lock)
chi_lock = threading.Lock()
chi_Cond = threading.Condition(lock=chi_lock)
class huofu(threading.Thread):
    def __init__(self,name):
        threading.Thread.__init__(self)
        self.setName(name)
    def run(self):
        while True:
            # 加锁
            zheng_Cond.acquire()
            if len(zhenglong)==0:
                # 开始蒸包子
                for i in range(1,11):
                    zhenglong.append(i)

                                    time.sleep(0.1)

                    print('正在蒸第{0}个包子',format(i)       
  print('正在蒸第{0}个包子',format(i))
                print('包子蒸完了 唤醒吃货们 开始吃包子。。')
                chi_Cond.notify_all()  # 唤醒了吃货们
            chi_Cond.release()   # 唤醒了伙夫 他就释放
            # 伙夫 进入休眠
            zheng_Cond.acquire()
            zheng_Cond.wait()
            zheng_Cond.release()


class chihuo(threading.Thread):
    def __init__(self,name):
        threading.Thread.__init__(self)
        self.setName(name)
    def run(self):
        while True:
            chi_Cond.acquire()   # 同一时刻只有一个吃货在获取 吃包子的资源
            global zhenglong
            # 同一时刻只有一个吃货在获取 吃包子的资源
            if len(zhenglong)==0:
                # 开始呼唤伙夫 只叫一次 蒸包子 我和其他吃货一同进入休眠
                zheng_Cond.acquire()  # 锁定叫醒伙夫的线程
                zheng_Cond.notify()   # 唤醒
                zheng_Cond.wait()     # 释放
                chi_Cond.wait()       # 这个吃货进入休眠
            else:
                baozi=zhenglong.pop()
                print(' {0} 吃了第{1}个包子 剩余{2}个包子'
                .format(self.getName(),baozi,len(zhenglong)))
                time.sleep(0.1)
            chi_Cond.release()
W=huofu('伙夫')
xiaoming=chihuo('小明')
xiaohong=chihuo('小红')
xiaopangzi=chihuo('小胖子')
W.start()
xiaoming.start()
xiaohong.start()
xiaopangzi.start()
# 主线程不死
input()

猜你喜欢

转载自blog.csdn.net/hwj990/article/details/80517908