念念不忘,必有回响!繁华似锦觅安宁,淡云流水度此生--------潇洒若梦&&浮生执铭
潇洒浮生
因为你 我愿意热爱整个世界

什么是线程

开启线程的两种方式

和开启进程的两种方式相似,只不过改一下导入的模块

进程与线程之间的区别:

  1. 开进程的开销远大于开线程
  2. 同一进程内多个线程共享该进程的内存空间
  3. Pid相同

     

    Tread 方法

    from threading import Thread,currentThread,active_count,enumerate
    import time

    def task():
    print('%s is running'% currentThread().getName())
    time.sleep(1)
    print('%s is done'% currentThread().getName())

    if __name__=='__main__':
    t = Thread(target=task,name='线程1') # name 设置线程名
    t.start()
    t.setName('线程-1') # 设置线程名
    print(t.getName()) # 获取线程名
    print(t.is_alive(),t.isAlive())
    t.join() # 等待线程执行完
    print(t.isAlive())
    print(currentThread().getName()) # 获取当前线程,在主线程下获取的就是主线程名
    currentThread().setName('main线程') # 设置当前线程名
    print('主线程',currentThread().getName())

    print(active_count()) # 先导入active_count 查看活跃线程数目
    print(enumerate()) # 先导入enumerate 查看线程

     

    守护线程

    from threading import Thread
    import time
    def foo():
    print(123)
    time.sleep(1)
    print('end123')
    def bar():
    print(456)
    time.sleep(3)
    print('end456')
    if __name__=='__main__':
    t1 = Thread(target=foo)
    t2 = Thread(target=bar)

    t1.setDaemon(True) # 等价于t1.daemon = True

    t1.start()
    t2.start()
    print('--main--')

    守护线程等到非守护线程结束才结束。

    互斥锁

    from threading import Thread,Lock
    import time

    n = 100
    def task():
    global n
    mutex.acquire()
    temp = n
    time.sleep(0.1)
    n = temp - 1
    mutex.release()
    if __name__ == '__main__':
    t_list = []
    mutex = Lock()
    for i in range(100):
    t = Thread(target=task,)
    t.start()
    t_list.append(t)
    for i in t_list:
    i.join()

    print(n)

     

    0

     

    死锁

    当两个线程互相争取对方现有的锁,就会造成死锁的现象。

    递归锁

    可以连续acquire多次,每acquire一次计数器加1,只有计数器为0时,其他线程才可以抢到该锁。

    from threading import Thread,RLock
    import time

    mutexA = mutexB = RLock()
    class MyThread(Thread):
    def run(self):
    self.f1()
    self.f2()
    def f1(self):
    mutexA.acquire()
    print('%s 拿到A锁'%self.name)
    mutexB.acquire()
    print('%s 拿到B锁' % self.name)
    mutexB.release()
    mutexA.release()

    def f2(self):
    mutexB.acquire()
    print('%s 拿到B锁' % self.name)
    time.sleep(3)
    mutexA.acquire()
    print('%s 拿到A锁' % self.name)
    mutexA.release()
    mutexB.release()

    if __name__=='__main__':
    for i in range(5):
    t = MyThread()
    t.start()

     

    Thread-1 拿到A

    Thread-1 拿到B

    Thread-1 拿到B

    Thread-1 拿到A

    Thread-2 拿到A

    Thread-2 拿到B

    Thread-3 拿到A

    Thread-3 拿到B

    Thread-3 拿到B

    Thread-3 拿到A

    Thread-5 拿到A

    Thread-5 拿到B

    Thread-2 拿到B

    Thread-2 拿到A

    Thread-4 拿到A

    Thread-4 拿到B

    Thread-5 拿到B

    Thread-5 拿到A

    Thread-4 拿到B

    Thread-4 拿到A

    信号量

    有10个人上公共厕所,公共厕所只有五个坑,同一时间最多可以有五个人同时上厕所。

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

    sem = Semaphore(5)

    def task():
    # sem.acquire()
    # print('%s get'% currentThread().getName())
    # sem.release()
    with sem: # 与上边等价,这种方式更简洁
    print('%s get' % currentThread().getName())
    time.sleep(random.randint(1,5))
    print('%s out' % currentThread().getName())
    if __name__=='__main__':
    for i in range(10):
    t = Thread(target=task)
    t.start()

     

    Thread-1 get

    Thread-2 get

    Thread-3 get

    Thread-4 get

    Thread-5 get

    Thread-5 out

    Thread-6 get

    Thread-6 out

    Thread-7 get

    Thread-1 out

    Thread-8 get

    Thread-3 out

    Thread-2 out

    Thread-9 get

    Thread-10 get

    Thread-7 out

    Thread-4 out

    Thread-8 out

    Thread-9 out

    Thread-10 out

    Event

    from threading import Thread,Event
    import time
    event = Event()

    def student(name):
    print('%s 正在听课'% name)
    event.wait() # 括号里面加上数字就是等待时间
    print('%s 课间活动'% name)

    def teacher(name):
    print('%s 正在授课'%name)
    time.sleep(7)
    print('%s 下课' % name)
    time.sleep(0.1)
    event.set()


    if __name__ == '__main__':
    s1 = Thread(target=student,args=('rose',))
    s2 = Thread(target=student, args=('lucy',))
    s3 = Thread(target=student, args=('lily',))

    t = Thread(target=teacher, args=('luli',))

    s1.start()
    s2.start()
    s3.start()
    t.start()

     

    rose 正在听课

    lucy 正在听课

    lily 正在听课

    luli 正在授课

    luli 下课

    rose 课间活动

    lily 课间活动

    lucy 课间活动

     

     

    # from threading import Thread,Event
    # import time
    # event = Event()
    #
    # def student(name):
    # print('%s 正在听课'% name)
    # event.wait() # 括号里面加上数字就是等待时间
    # print('%s 课间活动'% name)
    #
    # def teacher(name):
    # print('%s 正在授课'%name)
    # time.sleep(7)
    # print('%s 下课' % name)
    # time.sleep(0.1)
    # event.set()
    #
    #
    # if __name__ == '__main__':
    # s1 = Thread(target=student,args=('rose',))
    # s2 = Thread(target=student, args=('lucy',))
    # s3 = Thread(target=student, args=('lily',))
    #
    # t = Thread(target=teacher, args=('luli',))
    #
    # s1.start()
    # s2.start()
    # s3.start()
    # t.start()


    from threading import Thread,Event,currentThread
    import time
    event = Event()

    def conn():
    n=0
    while not event.is_set(): # event 是否被设置
    if n == 3:
    print('%s try too many times'% currentThread().getName())
    return
    n += 1
    event.wait(0.5)
    print('%s try %s time'%(currentThread().getName(),n))
    print('%s is connected'%currentThread().getName())

    def check():
    print('%s is checking'%currentThread().getName())
    time.sleep(5)
    event.set()

    if __name__ =='__main__':
    for i in range(3):
    con = Thread(target=conn)
    con.start()

    check = Thread(target=check)
    check.start()

     

    Thread-4 is checking

    Thread-2 try 1 time

    Thread-1 try 1 time

    Thread-3 try 1 time

    Thread-1 try 2 time

    Thread-3 try 2 time

    Thread-2 try 2 time

    Thread-1 try 3 time

    Thread-1 try too many times

    Thread-2 try 3 time

    Thread-3 try 3 time

    Thread-3 try too many times

    Thread-2 try too many times

     

    定时器

    验证码刷新

    from threading import Timer
    import random
    class Code:
    def __init__(self):
    self.make_cache()
    def make_cache(self,interval=10):
    self.cache = self.make_code()
    print(self.cache)
    self.t = Timer(interval,self.make_cache) # 这个地方是函数名,如果是函数名()会报错
    self.t.start()
    def make_code(self,):
    res = ''
    for
    i in range(4):
    s1=str(random.randint(0,9))
    s2 = chr(random.randint(65,90)) # 大写字母
    res += random.choice([s1,s2])
    return res
    def check(self):
    while True:
    code = input('验证码:').strip()
    print('验证码 %s'%self.cache)
    print('输入:%s'% code.upper())
    if code.upper() == self.cache: # 不用区分大小写
    print('正确')
    self.t.cancel()
    break
    obj = Code()
    obj.check()

     

     

    线程queue

     

     

    多线程实现并发套接字通信

     

    进程池线程池

    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import os,time,random

    def task(name):
    print('name:%s pid:%s'%(name,os.getpid()))
    time.sleep(random.randint(1,3))

    if __name__=='__main__':
    pool = ThreadPoolExecutor(4)
    for i in range(10):
    pool.submit(task,'id %s'%i)

    pool.shutdown() # 等待进程执行结束
    print('主')

     

    name:id 0 pid:8892

    name:id 1 pid:8892

    name:id 2 pid:8892

    name:id 3 pid:8892

    name:id 4 pid:8892

    以上代码实现的是线程池,如果实现进程池只要改一行代码:

    Pool = ProcessPoolExecutor(4)就ok了

     

    同步调用异步调用

    同步调用

    from concurrent.futures import ThreadPoolExecutor
    import time,random

    def work(name):
    print('%s is working'%name)
    time.sleep(random.randint(2,5))
    res = random.randint(8,24)
    return {'name':name,'hours':res}
    def count(res):
    name = res['name']
    num = res['hours']*10
    print('%s 制造了%s个艺术品'%(name,num))

    if __name__ =='__main__':
    pool = ThreadPoolExecutor(10)

    worker1 = pool.submit(work,'1').result()
    count(worker1)

    worker2 = pool.submit(work, '2').result()
    count(worker2)

    worker3 = pool.submit(work, '3').result()
    count(worker3)

     

    1 is working

    1 制造了120个艺术品

    2 is working

    2 制造了240个艺术品

    3 is working

    3 制造了170个艺术品

     

    异步调用

    from concurrent.futures import ThreadPoolExecutor
    import time,random

    def work(name):
    print('%s is working'%name)
    time.sleep(random.randint(2,5))
    res = random.randint(8,24)
    return {'name':name,'hours':res}
    def count(res):
    res = res.result() # future对象此时已经执行完毕,获取future对象的结果
    name = res['name']
    num = res['hours']*10
    print('%s 制造了%s个艺术品'%(name,num))

    if __name__ =='__main__':
    pool = ThreadPoolExecutor(10)

    pool.submit(work,'1').add_done_callback(count) # 调用count方法并把结果future对象传给方法

    pool.submit(work, '2').add_done_callback(count)

    pool.submit(work, '3').add_done_callback(count)

     

    1 is working

    2 is working

    3 is working

    3 制造了220个艺术品

    2 制造了200个艺术品

    1 制造了170个艺术品

posted on 2018-09-17 11:50  潇洒浮生  阅读(173)  评论(0编辑  收藏  举报

levels of contents