Python中的多线程编程实例教程
程序员文章站
2022-05-16 21:10:22
前言:
线程是操作能够进行运算调度的最小单位(程序执行流的最小单元)
它被包含在进程之中,是进程中的实际运作单位
一个进程中可以并发多个线程每条线程并行执行不同的任务
(线程是进程中的一个实体,是被...
前言:
线程是操作能够进行运算调度的最小单位(程序执行流的最小单元)
它被包含在进程之中,是进程中的实际运作单位
一个进程中可以并发多个线程每条线程并行执行不同的任务
(线程是进程中的一个实体,是被系统独立调度和分派的基本单元)
每一个进程启动时都会最先产生一个线程,即主线程
然后主线程会再创建其他的子线程
一、创建子线程
1.创建一个子线程
from threading import thread def foo(arg): print arg print 'before' # 线程和函数建立关系 t1 = thread(target=foo, args=(1,)) t1.start() print 'after'
2.创建多个子线程
# 导入创建子线程的工具 from threading import thread def foo(arg): print arg print 'before' # 利用thread创建一个子线程t1 # target是调用的函数,args是调用函数的参数,单个参数后要加逗号 t1 = thread(target=foo,args=(1,)) # 启动子线程 t1.start() #输出子线程的名称 print t1.getname() t2 = thread(target=foo,args=(2,)) t2.start() print t2.getname() print 'after'
3.模拟问题
import threading import queue import time import random def producer(name,que): while true: if que.qsize() <3: que.put('baozi') print '%s:made a baozi..=============' % name else: print '还有三个包子' time.sleep (random.randrange(5)) def consumer(name,que): while true: try: que.get_nowait() print '%s:got a baozi..' % name except exception: print '没有包子了' time.sleep(random.randrange(3)) # 创建队列 q = queue.queue() p1 = threading.thread(target=producer,args=['chef1',q]) p2 = threading.thread(target=producer,args=['chef2',q]) p1.start() p2.start() c1 = threading.thread(target=consumer,args=['tom',q]) c2 = threading.thread(target=consumer,args=['harry',q]) c1.start() c2.start()
二、主线程和子线程的执行等待问题
一个多线程程序,当主线程创建之后又有其他的子线程,就存在执行完成的先后顺序
1.主线程执行完毕不等待子线程
from threading import thread import time def foo(arg): for item in range(10): print item time.sleep(1) print 'before' t1 = thread(target=foo,args=(1,)) # 主线程执行完就结束程序,不在乎子线程的结束与否 # 主进程执行完了就不再等待子线程,false表示等待子线程 t1.setdaemon(true) t1.start() print 'after'
2.决定主线程等待子线程的时间
join()括号中可以写主线程等待子线程的时间
不写表示等待子线程执行完主线程再开始执行
from time import sleep from threading import thread def foo(): for item in range(10): print item sleep(1) print 'before' # 线程和函数建立关系 t1 = thread(target=foo) t1.start() # 主线程到join()就不往下进行了,直到子线程执行完 t1.join(5) print 'after'
三、子线程完成多件任务
创建子线程来模拟同时看电影和听音乐
from threading import thread from time import ctime,sleep def music(a): for i in range(1): print 'i was listening to %s. %s\n' % (a,ctime()) sleep(1) def movie(b): for i in range(1): print 'i was watching to %s. %s\n' % (b,ctime()) sleep(5) # music('hello') # movie('titanic') t1 = thread(target=music,args=('hello',)) t1.start() t2 = thread(target=movie,args=('titanic',)) t2.start() t2.join() print 'all over %s' % ctime()
运行结果如下,可以看到看电影和听音乐同时进行
四、线程安全问题
1.基本概念
线程不安全:就是不提供数据访问保护,在多线程环境中对数据进行修改,会出现数据不一致的情况。
线程安全:就是多线程环境中有对全局变量的变动时,需要对执行的代码块采用锁机制,当一个线程访问到某个数据时,其他线程需要等待当前线程执行完该代码块才可执行,不会出现数据不一致或者数据被污染。
如果一段代码在被多个线程执行,如果每次运行结果和单线程运行的结果是一样的,而且其他变量的值和预期一样,就是线程安全的。
线程安全主要由对有全局变量或静态变量有修改动作而引起的。
2.实例演示
import threading import time num = 0 def run(n): time.sleep(1) global num num += 1 print '%s\n' % num for i in range(1500): t=threading.thread(target=run,args =(i,)) t.start()
进行改进:
import threading import time num = 0 def run(n): time.sleep(1) global num # 对数据加锁 lock.acquire() num += 1 print '%s\n' % num # 释放加的锁 lock.release() # 生成一个锁 lock = threading.lock() for i in range(1500): t=threading.thread(target=run,args =(i,)) t.start()
推荐阅读