【Python】多线程-2

1、    进程和线程的区别:

(1) 一个进程可以有多个线程,一个进程中的多个线程共享该进程的所有资源,多线程切换比多进程切换快,因为不用上下文切换,Python中并发建议用多进程

(2) 进程是资源分配的最小单位,线程是程序执行的最小单位

(3) 进程有自己的独立地址空间,而线程是共享进程中的数据

2、    并行和并发:并行指在某一秒,并发指在某一时间段

3、    Pip list 查看各API版本号

4、    守护线程:比如主线程A中创建了子线程B,并且在主线程A中调用了B.setDeamon(),意思是,把B设置为守护线程,这时候,要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出。这就是 setDaemon方法的含义, 这基本和 join是相反的。此外,还有个要特别注意必须在 start()方法调用之前调用此方法,如果不设置为守护线程程序有可能会被无线挂起

5、    线程创建的方法:

(1) threading.Thread创建

(2) 通过继承Thread类创建线程 : class MyThread(threading.Thread)

6、    线程拥有的方法:

(1) isAlive() 返回线程是否在运行。运行指启动后,结束前。

(2) getName() 获取线程名字

(3) setName() 设置线程名字

(4) isDeamon() 判断线程是否随主线程一起结束

(5) setDeamon() 设置是否为守护线程

(6) start() 启动线程

(7) join() 等待所有子线程执行完后才能接着往下执行

(8) run() 用于表示线程活动的方法,通常需要重写

(9) pool.map()

7、    并发线程的两种关系:同步与互斥

(1) 锁可以实现线程间的互斥

(2) 生产者和消费者是线程同步的例子

8、    线程加锁:threading.Semaphore()

#练习:守护进程
import multiprocessing
import time, logging
import sys

def daemon():
  p = multiprocessing.current_process()
  print 'Starting:', p.name, p.pid
  sys.stdout.flush() # 将缓冲区数据写入终端
  # time.sleep(2)
  print 'Exiting :', p.name, p.pid
  sys.stdout.flush()

def non_daemon():
  p = multiprocessing.current_process()
  print 'non_Starting:', p.name, p.pid
  sys.stdout.flush()
  print 'non_Exiting :', p.name, p.pid
  sys.stdout.flush()

if __name__ == '__main__':
  # 设置日志输出到控制台
  multiprocessing.log_to_stderr()
  logger = multiprocessing.get_logger()
  # 设置输出日志的级别
  logger.setLevel(logging.DEBUG)

  d = multiprocessing.Process(name='daemon', target=daemon)
  d.daemon = True
  n = multiprocessing.Process(name='non-daemon', target=non_daemon)
  n.daemon = False
  d.start()
  time.sleep(1)
  n.start()
  # d.join(1)
  # n.join()
  print 'd.is_alive()', d.is_alive()
  print "n.is_alive()", n.is_alive()
  print "main Process end!"



#练习:线程池

import time
from multiprocessing.dummy import Pool as ThreadPool
#ThreadPool表示给线程池取一个别名ThreadPool

def run(fn):
    time.sleep(2)
    print fn

if __name__ == "__main__":
    testFL = [1,2,3,4,5]
    #创建10个容量的线程池并发执行
    pool = ThreadPool(10)
    pool.map(run,testFL)
    pool.close()
    pool.join()



#练习:锁可以实现线程间的互斥
import threading
import time

data = 0
lock = threading.Lock()#创建一个锁对象

def func() :
  global data
  print "%s acquire lock...
" %threading.currentThread().getName()
  if lock.acquire : #if 1:改成这个耗时会长
    print "%s get lock...
" %threading.currentThread().getName()
    for i in range(100000):
        data += 1 #must lock
    #time.sleep(2)#其它操作
    print "%s release lock...
" %threading.currentThread().getName()

    #调用release()将释放锁
    #lock.release()

startTime = time.time()
t1 = threading.Thread(target = func)
t2 = threading.Thread(target = func)
t3 = threading.Thread(target = func)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print data

endTime = time.time()
print "used time is", endTime - startTime

#练习:线程同步
from Queue import Queue #队列类
import random    
import threading    
import time      

#生成者线程
class Producer(threading.Thread):    
    def __init__(self, t_name, queue): 
        #调用父线程的构造方法。
        threading.Thread.__init__(self, name = t_name)    
        self.data = queue  

    def run(self):    
        for i in range(5):    
            print "%s: %s is producing %d to the queue!
" %(time.ctime(), self.getName(), i)  
            self.data.put(i)#向队列中添加数据
            #产生一个0-2之间的随机数进行睡眠
            time.sleep(random.randrange(10) / 5)    
        print "%s: %s finished!" %(time.ctime(), self.getName()) 
#消费者线程
class Consumer(threading.Thread):    
    def __init__(self, t_name, queue):    
        threading.Thread.__init__(self, name = t_name)  
        self.data = queue  

    def run(self):    
        for i in range(5):    
            val = self.data.get()#从队列中取出数据
            print "%s: %s is consuming. %d in the queue is consumed!
" %(time.ctime(), 

self.getName(), val)
            time.sleep(random.randrange(10))  
        print "%s: %s finished!" %(time.ctime(), self.getName()) 

#Main thread    
def main():    
    queue = Queue()#创建一个队列对象(特点先进先出)
    producer = Producer('Pro.', queue)#生产者对象
    consumer = Consumer('Con.', queue)#消费者对象
    producer.start()    
    consumer.start()  
    producer.join()    
    consumer.join()  
    print 'All threads terminate!'  

if __name__ == '__main__':  
    main()


#练习:线程锁
from threading import Thread, Lock
import threading

def run(lock, num):  
  lock.acquire() # 获得锁
  # 取得当前线程的线程名
  threadName = threading.current_thread().getName()
  print "%s, Hello Num: %s" %(threadName, num)  
  lock.release() # 释放锁

if __name__ == '__main__':  
    lock = Lock()  # 创建一个共享锁实例
    for num in range(20):  
      Thread(name = 'Thread-%s' %str(num), target = run, args = (lock, num)).start()


#练习:多把线程锁
from threading import Thread,Lock
import threading
import time

def worker(s,i):
    s.acquire()
    print(threading.current_thread().name + " acquire")
    time.sleep(i)
    print(threading.current_thread().name + " release")
    s.release()

if __name__=="__main__":
    s=threading.Semaphore(3)
    for i in range(5):
        t=Thread(target=worker,args=(s,i*2))
        t.start()
        #t.join #这里加了join就会逐个执行了
原文地址:https://www.cnblogs.com/jingsheng99/p/8850350.html