python多线程简单操作

python的线程类似于java 的线程,也区分守护线程和非守护线程。守护线程的作用就是为其他线程的运行提供便利。

缺省值为非守护程序线程。当该进程的所有非后台进程结束时,该进程将自动结束。

[En]

The default is a non-daemon thread. When all the non-daemons of the process end, the process ends automatically.

# 线程使用的方式一
import threading

# 需要多线程运行的函数
import time

def doPrint(param):
    current = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
    print(current + "\t" + str(param))

def fun(args):
    doPrint("线程开始, name: {}, args: {}".format(threading.current_thread().getName(), args))
    doPrint("thread is Daemon: " + str(threading.current_thread().isDaemon()))
    time.sleep(3)
    doPrint("线程结束, name: {}, args: {}".format(threading.current_thread().getName(), args))

if __name__ == '__main__':
    # 打印当前main 线程的信息
    doPrint(threading.current_thread().getName())
    doPrint(threading.current_thread().__class__)

    # 创建一个线程并且开始一个新的线程。 两个参数就可以。
    t1 = threading.Thread(target=fun, args=(1,))
    # t1 = threading.Thread(target=fun, name='t1', args=(1,), daemon=True)
    t1.start()

    time.sleep(1)
    doPrint("main thread end ")

结果:(您可以看到默认的线程规则是线程-{num})

[En]

Result: (you can see that the default thread rule is Thread- {num})

20220729174638  MainThread
20220729174638
20220729174638  线程开始, name: Thread-1, args: 1
20220729174638  thread is Daemon: False
20220729174639  main thread end
20220729174641  线程结束, name: Thread-1, args: 1

将其更改为第二个指定的名称,并将其设置为守护程序线程以查看日志,如下所示:

[En]

Change it to the second specified name, and set it to the daemon thread to view the log as follows:

20220729174843  MainThread
20220729174843
20220729174843  线程开始, name: t1, args: 1
20220729174843  thread is Daemon: True
20220729174844  main thread end
import threading
import time

def doPrint(param):
    current = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
    print(current + "\t" + str(param))

class MyThreading(threading.Thread):
    def __init__(self, name):
        super(MyThreading, self).__init__()
        self.name = name

    # 线程要运行的代码
    def run(self):
        doPrint("线程开始, name: {}".format(threading.current_thread().getName()))
        doPrint("thread is Daemon: " + str(threading.current_thread().isDaemon()))
        time.sleep(3)
        doPrint("线程结束, name: {}".format(threading.current_thread().getName()))

if __name__ == '__main__':
    # 打印当前main 线程的信息
    doPrint(threading.current_thread().getName())
    doPrint(threading.current_thread().__class__)

    # 创建一个线程并且开始一个新的线程。 两个参数就可以。
    # t1 = threading.Thread(target=fun, args=(1,))
    t1 = MyThreading("cus-1")
    t1.start()

    time.sleep(1)
    doPrint("main thread end ")

结果:

[En]

Results:

20220729175358  MainThread
20220729175358
20220729175358  线程开始, name: cus-1
20220729175358  thread is Daemon: False
20220729175359  main thread end
20220729175401  线程结束, name: cus-1
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):
        """This constructor should always be called with keyword arguments. Arguments are:

        *group* should be None; reserved for future extension when a ThreadGroup
        class is implemented.

        *target* is the callable object to be invoked by the run()
        method. Defaults to None, meaning nothing is called.

        *name* is the thread name. By default, a unique name is constructed of
        the form "Thread-N" where N is a small decimal number.

        *args* is the argument tuple for the target invocation. Defaults to ().

        *kwargs* is a dictionary of keyword arguments for the target
        invocation. Defaults to {}.

        If a subclass overrides the constructor, it must make sure to invoke
        the base class constructor (Thread.__init__()) before doing anything
        else to the thread.

"""
        assert group is None, "group argument must be None for now"
        if kwargs is None:
            kwargs = {}
        self._target = target
        self._name = str(name or _newname())
        self._args = args
        self._kwargs = kwargs
        if daemon is not None:
            self._daemonic = daemon
        else:
            self._daemonic = current_thread().daemon
        self._ident = None
        if _HAVE_THREAD_NATIVE_ID:
            self._native_id = None
        self._tstate_lock = None
        self._started = Event()
        self._is_stopped = False
        self._initialized = True
        # Copy of sys.stderr used by self._invoke_excepthook()
        self._stderr = _sys.stderr
        self._invoke_excepthook = _make_invoke_excepthook()
        # For debugging and _after_fork()
        _dangling.add(self)

threading.Thread.run 线程默认的run 方法:

    def run(self):
        """Method representing the thread's activity.

        You may override this method in a subclass. The standard run() method
        invokes the callable object passed to the object's constructor as the
        target argument, if any, with sequential and keyword arguments taken
        from the args and kwargs arguments, respectively.

"""
        try:
            if self._target:
                self._target(*self._args, **self._kwargs)
        finally:
            # Avoid a refcycle if the thread is running a function with
            # an argument that has a member that points to the thread.

            del self._target, self._args, self._kwargs

​ 可以看出, 如果传了target 参数,会调用方法,传入的参数就是自身的两个属性 _args(tuple 元组类型) 和 _kwargs(dict类型)

# 线程使用的方式一
import threading

# 需要多线程运行的函数
import time

def doPrint(param):
    current = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
    print(current + "\t" + str(param))

def fun(args):
    doPrint("线程开始, name: {}, args: {}".format(threading.current_thread().getName(), args))
    doPrint("thread is Daemon: " + str(threading.current_thread().isDaemon()))
    time.sleep(3)
    doPrint("线程结束, name: {}, args: {}".format(threading.current_thread().getName(), args))

if __name__ == '__main__':
    # 打印当前main 线程的信息
    doPrint(threading.current_thread().getName())
    doPrint(threading.current_thread().__class__)

    # 创建一个线程并且开始一个新的线程。 两个参数就可以。
    t1 = threading.Thread(target=fun, args=(1,))
    t1.start()
    # join 方法相当于当前线程等待join 的方法完成,类似于同步的效果。 可以传一个timeout  参数,指定超时时间
    t1.join()

    time.sleep(1)
    doPrint("main thread end ")

结果:

[En]

Results:

20220729180843  MainThread
20220729180843
20220729180843  线程开始, name: Thread-1, args: 1
20220729180843  thread is Daemon: False
20220729180846  线程结束, name: Thread-1, args: 1
20220729180847  main thread end
import random
import threading
import time
from concurrent.futures import ThreadPoolExecutor

def doPrint(param):
    current = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
    print(current + "\t" + threading.current_thread().getName() + "\t" + str(param))

def task(video_url):
    doPrint("开始执行任务" + video_url)
    time.sleep(1)
    # 将结果封装成一个Futuer对象,返回给线程池
    return random.randint(0, 10)

# response就是futuer对象,也就是task的返回值分装的一个Futuer对象
def done(response):
    # 即Futuer.result():取出task的返回值
    doPrint("任务执行完后,回调的函数" + str(response.result()))

# 创建线程池
threadpool = ThreadPoolExecutor(10)
url_list = ["www.xxxx-{}.com".format(i) for i in range(5)]
for url in url_list:
    # futuer是由task返回的一个Future对象,里面有记录task的返回值
    futuer = threadpool.submit(task, url)
    # 回调done函数,执行者依然是子线程
    futuer.add_done_callback(done)

doPrint("等待线程池中的任务执行完毕中······")
threadpool.shutdown(True)  # 等待线程池中的任务执行完毕后,在继续执行
doPrint("END")

结果:

[En]

Results:

20220729205033  ThreadPoolExecutor-0_0  开始执行任务www.xxxx-0.com
20220729205033  ThreadPoolExecutor-0_1  开始执行任务www.xxxx-1.com
20220729205033  ThreadPoolExecutor-0_2  开始执行任务www.xxxx-2.com
20220729205033  ThreadPoolExecutor-0_3  开始执行任务www.xxxx-3.com
20220729205033  ThreadPoolExecutor-0_4  开始执行任务www.xxxx-4.com20220729205033  MainThread  等待线程池中的任务执行完毕中······

20220729205034  ThreadPoolExecutor-0_0  任务执行完后,回调的函数3
20220729205034  ThreadPoolExecutor-0_1  任务执行完后,回调的函数9
20220729205034  ThreadPoolExecutor-0_4  任务执行完后,回调的函数6
20220729205034  ThreadPoolExecutor-0_2  任务执行完后,回调的函数3
20220729205034  ThreadPoolExecutor-0_3  任务执行完后,回调的函数3
20220729205034  MainThread  END

Original: https://www.cnblogs.com/qlqwjy/p/16534566.html
Author: QiaoZhi
Title: python多线程简单操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/6191/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部
最近整理资源【免费获取】:   👉 程序员最新必读书单  | 👏 互联网各方向面试题下载 | ✌️计算机核心资源汇总