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就会逐个执行了