前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python多线程使用和注意事项

Python多线程使用和注意事项

作者头像
py3study
发布2020-01-17 11:26:10
5240
发布2020-01-17 11:26:10
举报
文章被收录于专栏:python3python3

多线程

基本实现:

第一种,函数方式

# -*- 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]

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档