python 在threading中如何处理主进程和子线程的关系

之前用python的多线程,总是处理不好进程和线程之间的关系。后来发现了join和setDaemon函数,才终于弄明白。下面总结一下。

1.使用join函数后,主进程会在调用join的地方等待子线程结束,然后才接着往下执行。

join使用实例如下:

import time
import random
import threading

class worker(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
  def run(self):
    t = random.randint(1,10)
    time.sleep(t)
    print "This is " + self.getName() + ";I sleep %d second."%(t)

tsk = []
for i in xrange(0,5):
  time.sleep(0.1)
  thread = worker()
  thread.start()
  tsk.append(thread)
for tt in tsk:
  tt.join()
print "This is the end of main thread."

运行结果如下:

# python testjoin.py
This is Thread-3;I sleep 2 second.
This is Thread-1;I sleep 4 second.
This is Thread-2;I sleep 7 second.
This is Thread-4;I sleep 7 second.
This is Thread-5;I sleep 7 second.
This is the end of main thread.

这里创建了5个子线程,每个线程随机等待1-10秒后打印退出;主线程分别等待5个子线程结束。最后结果是先显示各个子线程,再显示主进程的结果。

2. 如果使用的setDaemon函数,则与join相反,主进程结束的时候不会等待子线程。

setDaemon函数使用实例:

import time
import random
import threading

class worker(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
  def run(self):
    t = random.randint(1,10)
    time.sleep(t)
    print "This is " + self.getName() + ";I sleep %d second."%(t)

tsk = []
for i in xrange(0,5):
  time.sleep(0.1)
  thread = worker()
  thread.setDaemon(True)
  thread.start()
  tsk.append(thread)
print "This is the end of main thread."

这里设置主进程为守护进程,当主进程结束的时候,子线程被中止

运行结果如下:

#python testsetDaemon.py
This is the end of main thread.

3、如果没有使用join和setDaemon函数,则主进程在创建子线程后,直接运行后面的代码,主程序一直挂起,直到子线程结束才能结束。

import time
import random
import threading

class worker(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
  def run(self):
    t = random.randint(1,10)
    time.sleep(t)
    print "This is " + self.getName() + ";I sleep %d second."%(t)

tsk = []
for i in xrange(0,5):
  time.sleep(0.1)
  thread = worker()
  thread.start()
  tsk.append(thread)
print "This is the end of main thread."

运行结果如下:

# python testthread.py
This is the end of main thread.
This is Thread-4;I sleep 1 second.
This is Thread-3;I sleep 7 second.
This is Thread-5;I sleep 7 second.
This is Thread-1;I sleep 10 second.
This is Thread-2;I sleep 10 second.

补充知识:Python Thread和Process对比

原因:进程和线程的差距(方向不同,之针对这个实例)

# coding=utf-8
import logging
import multiprocessing
import os
import time
from threading import Thread

logging.basicConfig(
  level=logging.INFO,
  format="%(asctime)s 【 %(process)d 】 %(processName)s %(message)s"
)

def func (i):
  # logging.info(f'子:{os.getpid()},\t{i}')
  return f'子:{os.getpid()},\t{i}'

def main (ctx):
  start01 = time.time()
  ts = [Thread(target=func, args=(i,)) for i in range(100)]
  [t.start() for t in ts]
  [t.join() for t in ts]
  end01 = time.time() - start01
  logging.info(f"线程花费的时间:{end01}秒")

  start02 = time.time()
  ps = [ctx.Process(target=func, args=(i,)) for i in range(100)]
  [p.start() for p in ps]
  [p.join() for p in ps]
  end02 = time.time() - start02
  logging.info(f"进程花费的时间:{end02}秒")

if __name__ == '__main__':
  # windows 启动方式
  multiprocessing.set_start_method('spawn')
  # 获取上下文
  ctx = multiprocessing.get_context('spawn')
  # 检查这是否是冻结的可执行文件中的伪分支进程。
  ctx.freeze_support()
  main(ctx)

输出:

2019-10-06 14:17:22,729 【 7412 】 MainProcess 线程花费的时间:0.012967586517333984秒
2019-10-06 14:17:25,671 【 7412 】 MainProcess 进程花费的时间:2.9418249130249023秒

以上这篇python 在threading中如何处理主进程和子线程的关系就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python中的线程threading.Thread()使用详解

    1. 线程的概念: 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源. 2. threading.thread()的简单使用 2.1 python的thread模块是比较底层的模块,python的t

  • python主线程与子线程的结束顺序实例解析

    这篇文章主要介绍了python主线程与子线程的结束顺序实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 引用自 主线程退出对子线程的影响 的一段话: 对于程序来说,如果主进程在子进程还未结束时就已经退出,那么Linux内核会将子进程的父进程ID改为1(也就是init进程),当子进程结束后会由init进程来回收该子进程. 主线程退出后子线程的状态依赖于它所在的进程,如果进程没有退出的话子线程依然正常运转.如果进程退出了,那么它所有的线程都会

  • Python线程threading模块用法详解

    本文实例讲述了Python线程threading模块用法.分享给大家供大家参考,具体如下: threading-更高级别的线程接口 源代码:Lib/threading.py 该模块在较低级别thread模块之上构建更高级别的线程接口.另请参见mutex和Queue模块. 该dummy_threading模块适用于threading因thread缺失而无法使用的情况 . 注意: 从Python 2.6开始,该模块提供 符合 PEP 8的别名和属性,以替换camelCase受Java的线程API启发

  • Python中多线程thread与threading的实现方法

    学过Python的人应该都知道,Python是支持多线程的,并且是native的线程.本文主要是通过thread和threading这两个模块来实现多线程的. python的thread模块是比较底层的模块,python的threading模块是对thread做了一些包装的,可以更加方便的被使用. 这里需要提一下的是python对线程的支持还不够完善,不能利用多CPU,但是下个版本的python中已经考虑改进这点,让我们拭目以待吧. threading模块里面主要是对一些线程的操作对象化了,创建

  • 对python:threading.Thread类的使用方法详解

    Python Thread类表示在单独的控制线程中运行的活动.有两种方法可以指定这种活动: 1.给构造函数传递回调对象 mthread=threading.Thread(target=xxxx,args=(xxxx)) mthread.start() 2.在子类中重写run() 方法 这里举个小例子: import threading, time class MyThread(threading.Thread): def __init__(self): threading.Thread.__in

  • python 在threading中如何处理主进程和子线程的关系

    之前用python的多线程,总是处理不好进程和线程之间的关系.后来发现了join和setDaemon函数,才终于弄明白.下面总结一下. 1.使用join函数后,主进程会在调用join的地方等待子线程结束,然后才接着往下执行. join使用实例如下: import time import random import threading class worker(threading.Thread): def __init__(self): threading.Thread.__init__(self

  • android中UI主线程与子线程深入分析

    本文较为深入的分析了android中UI主线程与子线程.分享给大家供大家参考.具体如下: 在一个Android 程序开始运行的时候,会单独启动一个Process.默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process. 一个Android 程序默认情况下也只有一个Process,但一个Pr

  • 修改Python的pyxmpp2中的主循环使其提高性能

    引子 之前clubot使用的pyxmpp2的默认mainloop也就是一个poll的主循环,但是clubot上线后资源占用非常厉害,使用strace跟踪发现clubot在不停的poll,查看pyxmpp2代码发现pyxmpp2的poll在使用超时阻塞时使用最小超时时间,而最小超时时间一直是0,所以会变成一个没有超时的非阻塞poll很浪费资源,不打算更改库代码,所以自己仿照poll的mainloop写了一个更加高效的epoll的mainloop 实现 #!/usr/bin/env python #

  • electron渲染进程主进程相互传值示例解析

    目录 在electron中分为渲染进程和主进程 浏览器传值给主进程 浏览器环境 主进程 主进程传值给渲染进程 主进程 渲染进程 注意 在electron中分为渲染进程和主进程 渲染进程就是浏览器环境,主进程就是node环境 既然他们是不同的环境,那么为我们怎么让他们相互关联起来呢?或者说怎么传递值? 毕竟在开发中可能会遇到我想要的值只能在node环境中才能获取,然后node中可能也会需要浏览器环境的值:这个时候就需要两个环境联通起来相互传值 浏览器传值给主进程 浏览器环境 引入: import

  • 解决python父线程关闭后子线程不关闭问题

    我们都知道,python可以通过threading module来创建新的线程,然而在创建线程的线程(父线程)关闭之后,相应的子线程可能却没有关闭,这可能是因为代码中没有使用setDaemon(True)函数. 接下来,使用一个例子来说明: import threading def prt_hello() : while 1 : print 'hello' if __name__ == '__main__' : t = threading.Thread(target=prt_hello) t.s

  • 基于Java子线程中的异常处理方法(通用)

    在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何在父线程中捕获来自子线程的异常,从而进行相应的处理呢? 常见错误 也许有人会觉得,很简单嘛,直接在父线程启动子线程的地方try ... catch一把就可以了,其实这是不对的. 原因分析 让我们回忆一下Runnable接口的run方法的完整签名,因为没有标识throws语句,所以方法是不会抛出checked异常的.至于Runtime

  • python多进程 主进程和子进程间共享和不共享全局变量实例

    Python 多进程默认不能共享全局变量 主进程与子进程是并发执行的,进程之间默认是不能共享全局变量的(子进程不能改变主进程中全局变量的值). 如果要共享全局变量需要用(multiprocessing.Value("d",10.0),数值)(multiprocessing.Array("i",[1,2,3,4,5]),数组)(multiprocessing.Manager().dict(),字典)(multiprocessing.Manager().list(ran

  • Python threading中lock的使用详解

    在多线程中使用lock可以让多个线程在共享资源的时候不会“乱”,例如,创建多个线程,每个线程都往空列表l中添加一个数字并打印当前的列表l,如果不加锁,就可能会这样: # encoding=utf8 import threading import time lock = threading.Lock() l = [] def test1(n): lock.acquire() l.append(n) print l lock.release() def test(n): l.append(n) pr

  • Python爬虫程序中使用生产者与消费者模式时进程过早退出的问题

    之前写爬虫程序的时候,采用生产者和消费者的模式,利用Queue作为生产者进程和消费者进程之间的同步队列. 执行程序时,总是秒退,加了断点也无法中断,加打印也无法输出,我知道肯定是进程退出了,但还是百思不得解,为什么会这么快就退出. 一开始以为是我的进程代码写的有问题,在某个地方崩溃导致程序提前退出,排查了一遍又一遍,并没有发现什么明显的问题,后来走读代码,看到主模块中消费者和生产者进程的启动后,发现了问题,原因是我通过start()方法启动进程后,使用join()的方式有问题.消费者进程必须执行

随机推荐