Python用GIL( global Interpretor Lock)和队列模型来处理资源的抢占问题,Python解释器不是线程安全的,需要持有这个锁,才可以安全访问python对象,因此,python不能很好的利用多CPU资源。

上一篇文章中讲了进程了,那么为什么还需要多线程呢,由于进程开销大,通信麻烦,所以需要多线程,多线程是在单独的进程中并发的执行任务。

线程状态:就绪 运行 休眠 中止

thread模块使用start_new_thread(func,(args1,args2...))start_new_thread此方法接收一个函数作为参数,并启动一个线程。 已经不推荐使用thread模块了。

threading模块

使用方法,继承threading.Thread 重写runimport threading,time

class ThreadDemo(threading.Thread):
def __init__(self,index,create_time):
threading.Thread.__init__(self)
self.index = index
self.create_time = create_time
def run(self):
time.sleep(1)
print (time.time()-self.create_time),"\t",self.index
print "Thread %d exit" % (self.index)
for x in range(5):
t = ThreadDemo(x,time.time())
t.start()

常用方法:start run join setDaemon isDaemon 注意start 和run 的区别

join注意两点:若不设置timeout,则join会一直阻塞至线程终止。线程不能在自己的运行代码中join,否则会死锁

W WW.002pc .COM认为此文章对《python excel 读 中文乱码python中线程的使用》说的很在理,第二电脑网为你提供最佳的python项目,python项目。

threading.local()不同线程中保存为不同的值。同java中的threadlocalimport threading,time,random

class ThreadLocal(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.local = threading.local()
def run(self):
time.sleep(random.random())
self.local.numbers = []
for i in range(10):
self.local.numbers.append(random.choice(range(10)))
print threading.currentThread,self.local.numbers
for x in range(5):
t = ThreadLocal()
t.start()

线程同步

临界资源临界资源,其实就是被多线程都会访问到的那段代码。关于临界资源的访问,多线程访问临界资源会导致非预期结果。例如,一个计数器的increase方法,调一次+1,若100个线程去调用,最后结果通常小于100,这事因为同时访问和修改导致的。

import threading
class Counter:
def __init__(self):
self.value = 0
def increase(self):
self.value += 1
return self.value
counter = Counter()
class ThreadDemo(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print counter.increase()
for x in range(100):
t = ThreadDemo()

t.start()结果基本都小于100,需要使用一些措施来避免出现这种问题。

thread锁机制使用thread.allocate_lock()来分配锁,然后acquire获取锁,执行完成后release释放,代码如下

import threading,thread
class Counter:
def __init__(self):
self.value = 0
self.lock = thread.allocate_lock()
def increase(self):
self.lock.acquire()
self.value += 1
self.lock.release()
return self.value
counter = Counter()
class ThreadDemo(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print counter.increase()
for x in range(100):
t = ThreadDemo()
t.start()

条件变量锁机制可以解决同步问题,但是遇到复杂的多线程问题就无能为力了。比如常见的生产者-消费者问题,线程间需要互相感知,这里就要用到条件变量。当然,使用条件变量同样也实现了锁的功能,提供acquire 和release方法,还提供notify notifyall wait

生产者与消费者的例子

from threading import Thread,Condition,currentThread
import time,random
class Producer(Thread):
def __init__(self,condition,goods):
Thread.__init__(self)
self.cond=condition
self.goods=goods
def run(self):
while 1:
self.cond.acquire()
self.goods.append(chr(random.randint(97, 122)))
print self.goods
cond.notifyAll()
cond.release()
time.sleep(random.choice(range(3)))
class Consumer(Thread):
def __init__(self,condition,goods):
Thread.__init__(self)
self.cond=condition
self.goods=goods
def run(self):
while 1:
cond.acquire()
while not goods:
print "has no good,wait..."
cond.wait()
print "consume:",goods.pop(0)
print self.goods
cond.release()
time.sleep(random.choice(range(2)))
goods=[]
cond=Condition()
p = Producer(cond,goods)
c = Consumer(cond,goods)
p.start()
c.start()