Python多线程实例

实例一

from threading import Thread, current_thread
import time

isStop = False  # 全局变量

def get(url):
    print(current_thread().name, ':正在下载', url)
    while True:
        if isStop:
            return
        time.sleep(1)
    print(current_thread().name, ':', url, '下载完成')


if __name__ == '__main__':
    print('----创建线程,开始下载----')
    t = Thread(target=get,
               name='Downloader',  # 指定线程的名称
               args=('http://www.hao123.com', ))

    t.start()
    time.sleep(2)
    # 停止线程
    isStop = True

    t.join()  # 等待子线程完成
    print('---完成所有下载任务---')

运行结果:

----创建线程,开始下载----
Downloader :正在下载 http://www.hao123.com
---完成所有下载任务---

实例二

from threading import Thread

import time

class MyThread(Thread):
    def __init__(self, name, counter):
        super().__init__()
        self.name = name
        self.counter = counter
        self.start()  # 启动线程

    def run(self):
        print(self.name, '开始计数')
        counter(self.name, 1, self.counter)
        print(self.name, '结束计数')


# 多个线程执行的函数
def counter(name, delay, count):
    while count:
        time.sleep(delay)
        print(name, '执行的时间: ', time.ctime(time.time()), '本次数->', count)
        count -= 1


if __name__ == '__main__':
    print('-----start----')
    t1 = MyThread('Counter-1', 5)
    t2 = MyThread('Counter-2', 4)

    t1.join()
    t2.join()
    print('-----over----')

运行结果:

-----start----
Counter-1 开始计数
Counter-2 开始计数
Counter-1 执行的时间:  Tue Nov 20 17:04:34 2018 本次数-> 5
Counter-2 执行的时间:  Tue Nov 20 17:04:34 2018 本次数-> 4
Counter-1 执行的时间:  Tue Nov 20 17:04:35 2018 本次数-> 4
Counter-2 执行的时间:  Tue Nov 20 17:04:35 2018 本次数-> 3
Counter-2 执行的时间:  Tue Nov 20 17:04:36 2018 本次数-> 2
Counter-1 执行的时间:  Tue Nov 20 17:04:36 2018 本次数-> 3
Counter-2 执行的时间:  Tue Nov 20 17:04:37 2018 本次数-> 1
Counter-2 结束计数
Counter-1 执行的时间:  Tue Nov 20 17:04:37 2018 本次数-> 2
Counter-1 执行的时间:  Tue Nov 20 17:04:38 2018 本次数-> 1
Counter-1 结束计数
-----over----

实例三

from threading import Thread, Lock

import time

class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name
        self.start()  # 启动线程

    def run(self):
        print(self.name, '开始计数')
        counter(self.name, 1)
        print(self.name, '结束计数')


count = 10  # 全局变量(多线程是共享的)
threadLock = Lock()  # 创建锁

# 多个线程执行的函数
def counter(name, delay):
    global count
    while count:
        time.sleep(delay)
        # 进入上下文环境时(__enter__),会调用threadLock.acquire()
        # 退出上下文环境时(__exit__),会调用threadLock.release()
        with threadLock:
            print(name, '执行的时间: ', time.ctime(time.time()), '本次数->', count)
            if count >= 1:
                count -= 1


if __name__ == '__main__':
    print('-----start----')
    t1 = MyThread('Counter-1')
    t2 = MyThread('Counter-2')

    t1.join()
    t2.join()
    print('-----over----')

运行结果:

-----start----
Counter-1 开始计数
Counter-2 开始计数
Counter-2 执行的时间:  Tue Nov 20 17:06:32 2018 本次数-> 10
Counter-1 执行的时间:  Tue Nov 20 17:06:32 2018 本次数-> 9
Counter-2 执行的时间:  Tue Nov 20 17:06:33 2018 本次数-> 8
Counter-1 执行的时间:  Tue Nov 20 17:06:33 2018 本次数-> 7
Counter-2 执行的时间:  Tue Nov 20 17:06:34 2018 本次数-> 6
Counter-1 执行的时间:  Tue Nov 20 17:06:34 2018 本次数-> 5
Counter-2 执行的时间:  Tue Nov 20 17:06:35 2018 本次数-> 4
Counter-1 执行的时间:  Tue Nov 20 17:06:35 2018 本次数-> 3
Counter-1 执行的时间:  Tue Nov 20 17:06:36 2018 本次数-> 2
Counter-2 执行的时间:  Tue Nov 20 17:06:36 2018 本次数-> 1
Counter-2 结束计数
Counter-1 执行的时间:  Tue Nov 20 17:06:37 2018 本次数-> 0
Counter-1 结束计数
-----over----

实例四(线程池)

# 自定义线程池
from threading import Thread, current_thread
from queue import Queue

import time
import random


class Task(Thread):
    '''
    工作线程-从任务队列中读取任务(函数对象和函数参数)
    '''

    def __init__(self, task_queue):
        super().__init__()
        self.task_queue: Queue = task_queue
        self.start()

    def run(self):
        while True:
            try:
                do_task, args = self.task_queue.get(False)
                do_task(*args)
                time.sleep(0.2)
            except:
                break


def doTask(*args):  # 具体执行任务
    print(current_thread().name, '正在执行任务:', args)
    time.sleep(random.uniform(0, 1))


class PoolManager:
    '''
    自定义线程池管理器
    '''
    def __init__(self, maxsize=10):
        self.threads = []  # 线程
        self.taskQueue = Queue()
        self.maxsize = maxsize  # 最大线程并发数

    def apply_async(self, *args):  # 发布任务
        self.taskQueue.put((doTask, args))

    def close(self):  # 停止发布任务,并开启线程
        self.init_threads()

    def init_threads(self):  # 创建线程并启动
        # 发布了2个任务, 用多少线程执行任务合适
        init_size = 1
        task_len = self.taskQueue.qsize()  # 获取任务队列的大小
        init_size = task_len // 10 + (1 if task_len % 10 > 0 else 0)

        # 判断需要的线程数是否超过最大线程数
        init_size = init_size if init_size < self.maxsize else self.maxsize

        for _ in range(init_size):
            self.threads.append(Task(self.taskQueue))

    def wait_all_complete(self):
        for t in self.threads:
            if t.is_alive():
                t.join()


if __name__ == '__main__':

    pool = PoolManager()

    print('---开始所有任务---')
    # 发布任务
    for i in range(15):
        pool.apply_async('www.baidu.com', 'index%d.html'%i)

    # 停止发布任务并启动线程来完成任务
    pool.close()

    pool.wait_all_complete()
    print('---所有任务完成---')

运行结果:

---开始所有任务---
Thread-1 正在执行任务: ('www.baidu.com', 'index0.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index1.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index2.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index3.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index4.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index5.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index6.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index7.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index8.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index9.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index10.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index11.html')
Thread-1 正在执行任务: ('www.baidu.com', 'index12.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index13.html')
Thread-2 正在执行任务: ('www.baidu.com', 'index14.html')
---所有任务完成---

实例五(队列)

from queue import Queue
from threading import Thread, Lock
import time

from redis import Redis

isExitFlag = False  # 是否退出中断子线程


class MyThread(Thread):
    def __init__(self,name,task_q):
        super().__init__()
        self.name = name
        self.task_q = task_q

        self.start()

    def run(self):
        print(self.name, '---start---')

        while not isExitFlag:
            task = self.task_q.blpop('taskQueue', timeout=1)  # 获取一项任务
            print(self.name, '--正在执行的任务-->', task)
            time.sleep(1)

        print(self.name, '---end---')


if __name__ == '__main__':

    print('--所有任务开始--')

    # work_queue = Queue(maxsize=10)  # 最大数量(任务数)为10 个
    work_queue = Redis('127.0.0.1', db=4)

    threads = [MyThread('Thread-%d'%i, work_queue) for i in range(3)]
    # work_lock = Lock()
    # 发布任务
    tasks = ['www.baidu.com',
             'www.hao123.com',
             'www.jd.com',
             'www.qf.edu',
             'www.qq.com',
             'www.google.com.cn']

    for task in tasks:
        # work_queue.put(task)
        work_queue.lpush('taskQueue', task)


    # 假如,队列为空后,等待 指定的时间(10秒)后,如果再没有任务(消息),则退出?
    while work_queue.llen('taskQueue'):
        pass

    isExitFlag = True  # 尝试停止所有线程

    for thread_ in threads:
        thread_.join()

    print('--所有任务完成--')
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值