zoukankan      html  css  js  c++  java
  • 线程

    什么是线程

    开启线程的两种方式

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

    进程与线程之间的区别:

    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个艺术品

  • 相关阅读:
    cf Inverse the Problem (最小生成树+DFS)
    cf Make It Nondeterministic (简单贪心)
    cf Learn from Life (简单贪心)
    hdu 5057 Argestes and Sequence (数状数组+离线处理)
    hdu 5056 Boring count (类似单调队列的做法。。)
    hdu 5055 Bob and math problem (很简单贪心)
    三样东西能让女人幸福一生
    第01课 OpenGL窗口(4)
    爱情要不要吃回头草?(林忆)
    第01课 OpenGL窗口(3)
  • 原文地址:https://www.cnblogs.com/yuliangkaiyue/p/9661270.html
Copyright © 2011-2022 走看看