zoukankan      html  css  js  c++  java
  • Python程序中的线程操作-创建多线程

    Python程序中的线程操作-创建多线程

    一、Python线程模块的选择

    Python提供了几个用于多线程的编程的模块,包括thread、threading和Queue等。thread和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强大的线程管理的功能。Queue模块允许用户创建一个可以用于多个线程之间共享输一局的队列数据结构。

    避免使用thread模块,因为更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突;其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。

    thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。

    二、threading模块

    multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍(官方链接)

    三、通过threading.Thread类创建线程

    3.1创建线程的方式一

    from threading import Thread
    import time
    def sayhi(name):
        time.sleep(2)
        print('%s say hello' %name)
        
    # t = Thread(target=sayhi, args=('nick',))
    # t.start()
    # print('主线程')
    if __name__ == '__main__':
        t=Thread(target=sayhi,args=('nick',))
        t.start()
        print('主线程')
    

    3.2创建线程的方式二

    from threading import Thread
    import time
    class Sayhi(Thread):
        def __init__(self,name):
            super().__init__()
            self.name=name
        def run(self):
            time.sleep(2)
            print('%s say hello' % self.name)
    
    
    if __name__ == '__main__':
        t = Sayhi('nick')
        t.start()
        print('主线程')
    

    四、多线程与多进程

    4.1pid的比较

    from threading import Thread
    from multiprocessing import Process
    import os
    
    
    def work():
        print('hello', os.getpid())
    
    
    if __name__ == '__main__':
        # part1:在主进程下开启多个线程,每个线程都跟主进程的pid一样
        t1 = Thread(target=work)
        t2 = Thread(target=work)
        t1.start()
        t2.start()
        print('主线程/主进程pid', os.getpid())
    
        # part2:开多个进程,每个进程都有不同的pid
        p1 = Process(target=work)
        p2 = Process(target=work)
        p1.start()
        p2.start()
        print('主线程/主进程pid', os.getpid())
    

    4.2开启效率的较量

    from threading import Thread
    from multiprocessing import Process
    import os
    
    def work():
        print('hello')
    
    if __name__ == '__main__':
        # 在主进程下开启线程
        t=Thread(target=work)
        t.start()
        print('主线程/主进程')
        '''
        打印结果:
        hello
        主线程/主进程
        '''
    
        # 在主进程下开启子进程
        t=Process(target=work)
        t.start()
        print('主线程/主进程')
        '''
        打印结果:
        主线程/主进程
        hello
        '''
    

    4.3内存数据的共享问题

    from threading import Thread
    from multiprocessing import Process
    import os
    
    
    def work():
        global n
        n = 0
    
    
    if __name__ == '__main__':
        # n=100
        # p=Process(target=work)
        # p.start()
        # p.join()
        # print('主',n) # 毫无疑问子进程p已经将自己的全局的n改成了0,但改的仅仅是它自己的,查看父进程的n仍然为100
    
        n = 1
        t = Thread(target=work)
        t.start()
        t.join()
        print('主', n)  # 查看结果为0,因为同一进程内的线程之间共享进程内的数据
    
    

    五、Thread类的其他方法

    Thread实例对象的方法:

    • isAlive():返回线程是否活动的。
    • getName():返回线程名。
    • setName():设置线程名。

    threading模块提供的一些方法:

    • threading.currentThread():返回当前的线程变量。
    • threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
    • threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

    5.1代码示例

    from threading import Thread
    import threading
    from multiprocessing import Process
    import os
    
    
    def work():
        import time
        time.sleep(3)
        print(threading.current_thread().getName())
    
    
    if __name__ == '__main__':
        # 在主进程下开启线程
        t = Thread(target=work)
        t.start()
    
        print(threading.current_thread().getName())
        print(threading.current_thread())  # 主线程
        print(threading.enumerate())  # 连同主线程在内有两个运行的线程
        print(threading.active_count())
        print('主线程/主进程')
    
        '''
        打印结果:
        MainThread
        <_MainThread(MainThread, started 140735268892672)>
        [<_MainThread(MainThread, started 140735268892672)>, <Thread(Thread-1, started 123145307557888)>]
        主线程/主进程
        Thread-1
        '''
    

    5.2join方法

    from threading import Thread
    import time
    
    
    def sayhi(name):
        time.sleep(2)
        print('%s say hello' % name)
    
    
    if __name__ == '__main__':
        t = Thread(target=sayhi, args=('nick',))
        t.start()
        t.join() #主线程等待子线程结束
        print('主线程')
        print(t.is_alive())
        '''
        nick say hello
        主线程
        False
        '''
    

    六、多线程实现socket

    6.1服务端

    import multiprocessing
    import threading
    
    import socket
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.bind(('127.0.0.1',8080))
    s.listen(5)
    
    def action(conn):
        while True:
            data=conn.recv(1024)
            print(data)
            conn.send(data.upper())
    
    if __name__ == '__main__':
    
        while True:
            conn,addr=s.accept()
    
    
            p=threading.Thread(target=action,args=(conn,))
            p.start()
    

    6.2客户端

    import socket
    
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect(('127.0.0.1',8080))
    
    while True:
        msg=input('>>: ').strip()
        if not msg:continue
    
        s.send(msg.encode('utf-8'))
        data=s.recv(1024)
        print(data)
    
  • 相关阅读:
    iOS中的NSTimer 和 Android 中的Timer
    正则表达式中*的使用小注意
    NSUrlConnection 和 NSUrlRequest 的关系
    iOS 中的第三方库管理工具
    Android 向Application对象添加Activity监听
    Android dp px转化公式
    Android 返回桌面的Intent
    Spring+SpringMVC+Hibernate小案例(实现Spring对Hibernate的事务管理)
    Equinox OSGi应用嵌入Jersey框架搭建REST服务
    在OSGI容器Equinox中嵌入HttpServer
  • 原文地址:https://www.cnblogs.com/Lin2396/p/11568437.html
Copyright © 2011-2022 走看看