多线程介绍

多线程多进程:
 
 进程和线程:
 线程:是操作系统能够进行运算调度的最小单位,它被包含在进程值之中。
    是进程中实际运作单位,一条线程指的是进程中一个单一顺序的控制流
    一个进程可以并发多个线程,每个线程并行执行不同的任务
   
    可以简单的理解为一推指令
   
   
 进程:要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,
    内存对各种资源管理的集合,
   
   
 进程要操作cpu,必须要现创建一个线程
 所有在同一个进程里的线程是共享同一块内存空间
 
 进程是资源的集合
 线程是执行任务的指令
 进程要执行任务也需要通过线程
 
 启动一个线程比启动一个进程要快。
 
 线程和进程的区别:
 1. 线程共享内存空间,进程的内存是相对对立的
 2. 子进程相对克隆父进程,子进程和父进程之间的资源是独立的,不共享;
 3. 同一个进程中的线程可以相互交流,两个进程进程进行通信必须通过中间件
 4. 创建新线程很简单,但新建进程需要对父进程进行一次克隆;
 5. 一个线程可以控制和操作同一进程里的其他线程
 6. 进程只能操作子进程
 
 
 
 无论启动多少个线程,有多少个CPU,
 Python在执行时都会淡定在同一时刻只允许一个线程运行。
 
 
 
 
 
多线程:
 
 两种写法:
 
 例1:简单的线程:
  import threading, time
  
  def run(n):
   print("task", n)
   time.sleep(5)
  
  t1 = threading.Thread(target=run, args=("t1",))
  t2 = threading.Thread(target=run, args=("t2",))
  
  t1.start()
  t2.start()
 
 
 例2:简单的线程:
  import threading
  class MyThread(threading.Thread):
   def __init__(self, n):
    super(MyThread, self).__init__()
    self.n = n
  
   def run(self):
    print("running task...", self.n)
  
  t1 = MyThread("t1")
  t2 = MyThread("t2")
  
  t1.start()
  #t1.join()  #加了这个后就相对串行了。要等到t1完成才能执行t2
  t2.start()
      #末尾默认就有,所有程序结束后才能结束
  
 例3:启动50个线程
  import threading, time
 
  def run(n):
   print("task", n)
   time.sleep(5)
   print("task %s finished ....." %n)
  
  for i in range(50):
   t = threading.Thread(target=run, args=("t%s" %i,))
   t.start() 
  
 例4:
  import threading, time
  
  class MyThread(threading.Thread):
   def __init__(self, n, sleeptime):
    super(MyThread, self).__init__()
    self.n = n
    self.sleeptime = sleeptime
  
   def run(self):
    print("running task...", self.n)
    time.sleep(self.sleeptime)
    print("task %s done !" % self.n)
  
  t1 = MyThread("t1", 2)
  t2 = MyThread("t2", 4)
  
  t1.start()
  t2.start()
  t1.join()           #要等待t1结果才能往下执行,相当wait
  print("=============")
  运行结果:
  running task... t1
  running task... t2
  task t1 done !
  =============
  task t2 done !
  
  
 例5:
  import threading, time
  
  def run(n):
   print("task", n)
   time.sleep(2)
   print("task %s finished ....." %n)
  obj_t = []
  for i in range(50):
   t = threading.Thread(target=run, args=("t%s" %i,))
   t.start()
   obj_t.append(t)
    
  print(threading.current_thread())   #当前线程
  print(threading.active_count())    #当前的活跃线程数
  
  for t in obj_t:
   t.join()
  
  print("===========all Done===========")
 
  
列6:
 每个程序有一个主线程,当主线程是看不见的。
 通过print(threading.active_count())
 可以看到线程数是所有子线程+1
 默认情况我们创建的线程都是子线程
 
 默认情况下,主线程执行顺序不受子线程的影响
 但主线的退出是要等待所有子线程执行结束才退出。
 主线程相当是主人,守护进程相当是仆人
 如果将子线程设置成守护进程后,主线程的退出不再等待守护执行结束再退出
 t.setDaemon(True)可以把当前子线程设置为守护线程,一定要在start前。
 
 
 import threading, time
 
 def run(n):
  print("task", n)
  time.sleep(2)
  print("task %s finished ....." %n)
 
 obj_t = []
 for i in range(50):
  t = threading.Thread(target=run, args=("t%s" %i,))
  t.setDaemon(True)                   #把当前线程设置为守护线程,一定要在start前。
  t.start()
  obj_t.append(t)
 
 print(threading.current_thread())
 print(threading.active_count())
 从这个程序运行的结果可以看出来,
 所有守护线程的 print("task %s finished ....." %n)都没有执行,就随主线程的结束而结束。
  
  
 在python中无论CPU是几核,同一时间执行只有一个线程
 上下文切换;
 调用操作系统的原生线程
 
 
 
 
 import threading, time
 
 def run(n):
  print("task", n)
  global num
  num += 1
  print("task %s finished ....." %n)
 
 obj_t = []
 num = 0
 for i in range(10):
  t = threading.Thread(target=run, args=("t%s" %i,))
  t.start()
  obj_t.append(t)
 
 for t in obj_t:
  t.join()
 
 print("===========all Done===========")
 print("num: ",num)
 
 输出结果:
  ask t0
  task t0 finished .....
  task t1
  task t1 finished .....
  task t2
  task t2 finished .....
  task t3
  task t3 finished .....
  task t4
  task t4 finished .....
  task t5
  task t5 finished .....
  task t6
  task t6 finished .....
  task t7
  task t7 finished .....
  task t8
  task t8 finished .....
  task t9
  task t9 finished .....
  ===========all Done===========
  num:  10

对于python2.x, 为了避免修改全局变量时出错,需要给程序加锁。
但加锁后程序就变串行的了
python3.x 加不加锁效果不明显,但实际修改全局变量时也都要加!!! 
 import threading, time
 
 def run(n):
  lock.acquire()      #申请锁
  print("task", n)
  global num
  num += 1
  print("task %s finished ....." %n)
  lock.release()      #释放锁
 
 lock = threading.Lock()     #建议锁对象
 #lock = threading.RLock()               #递归锁,当有多把锁相互作用的时候,需要用到
 obj_t = []
 num = 0
 for i in range(10):
  t = threading.Thread(target=run, args=("t%s" %i,))
  t.start()
  obj_t.append(t)
 
 for t in obj_t:
  t.join()
 
 print("===========all Done===========")
 print("num: ",num)  

猜你喜欢

转载自www.cnblogs.com/brace2011/p/9291707.html