zoukankan      html  css  js  c++  java
  • python中线程和进程(一)

    进程和线程

    • 进程:进程是计算机中程序正在执行的实例,是系统进行资源分配和调度的基本单位。
    • 线程:也被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针,寄存器集合和堆栈组成。

    线程和进程的关系:

    现代操作系统中,每一个进程都认为自己独占所有的计算机资源。进程好比一个国家,各个进程间不可以随便的共享数据,而线程就像是省份,同一个进程内的线程可以共享进程的资源,每一个线程拥有自己独立的堆栈。

    进程和程序的关系:

    程序是源代码编译后的文件,当该程序被操作系统加载到内存中,就是进程,进程中存放着指令和数据,它也是线程的容器。

    Python中的线程

    1. Thread类

    python中线程的开发使用标准库:threading

    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):
    
    • target:线程调用的对象,即目标函数
    • name: 线程名
    • args:为目标函数传递的实参,元组
    • kwargs:为目标函数关键字传参,字典

    2. 线程的启动

    import threading
    
    
    def worker():
        print("I'm working")
        print("Finished")
    
    t = threading.Thread(target=worker,name='worker') #创建线程对象
    t.start() # 启动线程
    

    可以通过threading.Thread创建一个线程对象,target指定目标函数,然后调用start方法进行启动线程。

    3. 线程的传参

    import threading
    import time
    
    
    def add(x,y):
        print("{} + {} = {}  线程ID:{}".format(x,y,x+y,threading.current_thread().ident))
    
    thread1 = threading.Thread(target=add,name='add1',args=(4,5)).start()
    time.sleep(1)
    thread2 = threading.Thread(target=add,name='add2',args=(10,),kwargs={'y':5}).start()
    time.sleep(1)
    thread3 = threading.Thread(target=add,name='add3',kwargs={'x':20,'y':5}).start()
    

    线程传参和函数传参没有什么区别,本质上就是函数传参。

    4. 线程的属性和方法

    threading的属性和方法

    名称 含义
    current_thread() 返回当前线程对象
    main_thread() 返回主线程对象
    active_count() 当前处于alive状态的线程数
    enumerate() 返回所有活着的线程的列表,不包括已经终止的线程和为开始的线程
    get_ident() 返回当前线程的ID

    Thread实例的属性和方法

    名称 含义
    name 名称,仅仅是一个标识。可以通过getName()获取,setName()设置该名称
    ident 线程ID
    is_alive() 返回线程是否活着
    start() 启动线程。每个线程必须且只能执行该方法一次
    run() 运行线程函数

    start和run的区别:
    使用start启动线程,会启动一个新的线程,而使用run方法,并没有启动新的线程,只有在主线程上调用一个普通的函数。

    5. daemon线程和non-daemon线程

    在Python中,构造线程时,可以设置daemon属性。默认daemon线程是None,即non-daemon线程。

    import time
    import threading
    
    
    def foo():
        time.sleep(5)
        for i in range(20):
            print(i)
    
    t = threading.Thread(target=foo,daemon=True) #修改成None
    t.start()
    print("main thread Exit")
    

    如果一个程序中只有daemon线程,那么主线程退出的时候,会结束所有的daemon线程,退出。
    总结:
    在一个程序中,如果有non-daemon线程的时候,主线程退出时,不会杀掉所有的daemon线程,直到所有的non-daemon线程全部结束,如果还有daemon线程,主线程退出的时候,会结束所有的daemon线程,然后退出。

    6. join方法

    import time
    import threading
    
    
    def foo(n):
        for i in range(n):
            print(i)
            time.sleep(1)
    
    t = threading.Thread(target=foo,args=(10,),daemon=True)
    t.start()
    t.join() # 设置join
    print("main thread Exit")
    

    设置join后,daemon线程执行完了,程序才会退出。
    join(timeout=None):
    一个线程中调用另一个线程的join方法,此时调用者将会被阻塞,直到被调线程终止。一个线程可以被join多次。调用谁的join方法,就要等谁。

    import time
    import threading
    
    
    def bar():
        while True:
            time.sleep(1)
            print("bar")
    
    
    def foo():
        print("t1's daemon = {}".format(threading.current_thread().isDaemon()))
        t2 = threading.Thread(target=bar)
        t2.start()
        print("t2's daemon = {}".format(t2.isDaemon()))
    
    
    t1 = threading.Thread(target=foo,daemon=True)
    t1.start()
    time.sleep(3)
    print("main thread exiting")
    

    只要主程序退出,2个工作线程就结束。

    import time
    import threading
    
    
    def bar():
        while True:
            time.sleep(1)
            print("bar")
    
    
    def foo():
        print("t1's daemon = {}".format(threading.current_thread().isDaemon()))
        t2 = threading.Thread(target=bar)
        t2.start()
        print("t2's daemon = {}".format(t2.isDaemon()))
        t2.join()
    
    
    t1 = threading.Thread(target=foo,daemon=True)
    t1.start()
    t1.join()
    time.sleep(3)
    
    print("main thread exiting")
    

    通过相互调用join方法,使线程结束不了。

    7. 定时器Timer

    class Timer(Thread):
        def __init__(self, interval, function, args=None, kwargs=None):
    

    threading.Timer继承自Thread,该类用来定义多久执行一个函数。
    start方法执行之后,Timer对象就会处于等待状态,等待了interval之后,开始执行function函数,如果在执行函数之前的等待阶段,使用了cancel方法,就会跳过执行函数。
    但是如果线程中的函数已经开始执行,cancel就没有效果了。

    import threading
    import logging
    import time
    
    
    FORMAT = '%(asctime)s %(threadName)s %(thread)d %(message)s'
    logging.basicConfig(format=FORMAT,level=logging.INFO)
    
    
    def worker():
        logging.info('in worker')
        time.sleep(2)
    
    t = threading.Timer(5,worker)
    t.setName('w1')
    t.cancel()  # 提前取消
    t.start()
    print(threading.enumerate())
    time.sleep(8)
    print(threading.enumerate())
    
    
  • 相关阅读:
    coco2dx--Permission denied
    在Winform中屏蔽UnityWebPlayer的右键以及自带Logo解决方案整理
    Setup Factory 程序打包
    T—SQL用法剪辑,方便以后查看
    如何用asp.net MVC框架、highChart库从sql server数据库获取数据动态生成柱状图
    微软ASP.NET MVC 学习地址
    一个用WPF做的简单计算器源代码
    wpMVVM模式绑定集合的应用
    windows phone上下文菜单ContextMenu的使用示例
    CListCtrl 防止闪烁,调整行显示长度
  • 原文地址:https://www.cnblogs.com/dianel/p/10477819.html
Copyright © 2011-2022 走看看