Python多线程使用和注意事项
程序员文章站
2024-01-24 11:01:46
多线程 基本实现: 第一种,函数方式 # -*- coding:utf-8 -*- import thread import time def print_time(threadName, delay): count = 0 while count < 5: time.sleep(delay) co ......
多线程
基本实现:
第一种,函数方式
# -*- coding:utf-8 -*-
import thread
import time
def print_time(threadname, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print '%s : %s' % (threadname, time.ctime(time.time()))
try:
thread.start_new_thread(print_time, ("thread-1", 2,))
thread.start_new_thread(print_time, ("thread-2", 4,))
except:
print "error!unable to start thread."
while 1:
pass
第二种,继承父类
# -*- coding:utf-8 -*-
import threading
import time
class mythread(threading.thread):
def __init__(self, thread_id, name, counter):
threading.thread.__init__(self)
self.thread_id = thread_id
self.name = name
self.counter = counter
def run(self):
print "starting:" + self.name
print_time(self.name, self.counter, 5)
print "exiting:" + self.name
def print_time(thread_name, delay, counter):
while counter:
time.sleep(delay)
print '%s : %s' % (thread_name, time.ctime(time.time()))
counter -= 1
thread1 = mythread(1, "thread-1", 1)
thread2 = mythread(2, "thread-2", 2)
thread1.start()
thread2.start()
线程同步的问题解决:锁
这里第一个线程执行的时候,第二个线程是等待状态的
# -*- coding:utf-8 -*-
import threading
import time
threadlock = threading.lock()
threads = []
class mythread(threading.thread):
def __init__(self, thread_id, name, counter):
threading.thread.__init__(self)
self.thread_id = thread_id
self.name = name
self.counter = counter
def run(self):
print "starting:" + self.name
threadlock.acquire()
print_time(self.name, self.counter, 5)
print "exiting:" + self.name
threadlock.release()
def print_time(thread_name, delay, counter):
while counter:
time.sleep(delay)
print '%s : %s' % (thread_name, time.ctime(time.time()))
counter -= 1
thread1 = mythread(1, "thread-1", 1)
thread2 = mythread(2, "thread2", 2)
thread1.start()
thread2.start()
threads.append(thread1)
threads.append(thread2)
for thread in threads:
thread.join()
线程优先级队列:
虽然开启了多个线程,不过打印顺序一定是:one按顺序到five
# -*- coding:utf-8 -*-
import threading
import time
import queue
exit_flag = 0
queue_lock = threading.lock()
work_queue = queue.queue(10)
thread_list = ["thread-1", "thread-2", "thread-3"]
name_list = ["one", "two", "three", "four", "five"]
threads = []
thread_id = 1
class mythread(threading.thread):
def __init__(self, thread__id, name, queue):
threading.thread.__init__(self)
self.thread__id = thread__id
self.name = name
self.queue = queue
def run(self):
print "starting:" + self.name
process_data(self.name, self.queue)
print "exiting:" + self.name
def process_data(thread_name, queue):
while not exit_flag:
queue_lock.acquire()
if not work_queue.empty():
data = queue.get()
queue_lock.release()
print "%s processing %s" % (thread_name, data)
else:
queue_lock.release()
time.sleep(2)
for t in thread_list:
thread = mythread(thread_id, t, work_queue)
thread.start()
threads.append(thread)
thread_id += 1
queue_lock.acquire()
for word in name_list:
work_queue.put(word)
queue_lock.release()
while not work_queue.empty():
pass
exit_flag = 1
for t in threads:
t.join()
这里的join函数重点解释下:
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞主线程直到其他线程结束,如果结束则跳转执行下一个线程的join函数
接下来看看多线程实际的案例:
多线程访问网站
# -*- coding:utf-8 -*-
import urllib2
import time
from threading import thread
class geturlthread(thread):
def __init__(self, url):
thread.__init__(self)
self.url = url
def run(self):
response = urllib2.urlopen(self.url)
print self.url, response.getcode()
def get_responses():
urls = [
'https://www.baidu.com',
'https://www.taobao.com',
'https://www.cnblogs.com',
'https://github.com',
'https://www.jd.com'
]
start = time.time()
threads = []
for url in urls:
thread = geturlthread(url)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print "time: % s" % (time.time() - start)
get_responses()
如果多个线程访问同一个变量,容易出问题,比如下面:
有可能最后的实际值并不是50
# -*- coding:utf-8 -*-
from threading import thread
some_var = 0
class incrementthread(thread):
def run(self):
global some_var
read_value = some_var
print "线程%s中的some_var是%d" % (self.name, read_value)
some_var = read_value + 1
print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
def use_increment_thread():
threads = []
for i in range(50):
thread = incrementthread()
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print "在50次运算后some_var应该变成50"
print "在50次运算后some_var实际值为:%d" % (some_var,)
use_increment_thread()
解决办法,加入一个锁:
这种情况,最后的实际值一定是50
# -*- coding:utf-8 -*-
from threading import thread, lock
lock = lock()
some_var = 0
class incrementthread(thread):
def run(self):
global some_var
lock.acquire()
read_value = some_var
print "线程%s中的some_var是%d" % (self.name, read_value)
some_var = read_value + 1
print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
lock.release()
def use_increment_thread():
threads = []
for i in range(50):
thread = incrementthread()
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print "在50次运算后some_var应该变成50"
print "在50次运算后some_var实际值为:%d" % (some_var,)
use_increment_thread()
另一个锁的案例:
不加锁容易出事
# -*- coding:utf-8 -*-
from threading import thread
import time
class createlistthread(thread):
def __init__(self):
self.entries = []
thread.__init__(self)
def run(self):
self.entries = []
for i in range(10):
time.sleep(1)
self.entries.append(i)
print self.entries
def use_create_list_thread():
for i in range(3):
t = createlistthread()
t.start()
use_create_list_thread()
结果:
[[[000, , , 111, , , 222, , , 333, , , 444, , , 555, , , 666, , , 777, , , 888, , , 999]]]
给他加上锁:
# -*- coding:utf-8 -*-
from threading import thread, lock
import time
lock = lock()
class createlistthread(thread):
def __init__(self):
self.entries = []
thread.__init__(self)
def run(self):
self.entries = []
for i in range(10):
time.sleep(1)
self.entries.append(i)
lock.acquire()
print self.entries
lock.release()
def use_create_list_thread():
for i in range(3):
t = createlistthread()
t.start()
use_create_list_thread()
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
上一篇: Java基础之垃圾回收机制(第一篇:性能监控与分析工具介绍)
下一篇: Apache 端口批改
推荐阅读