zoukankan      html  css  js  c++  java
  • 多线程,代码示例

    一。threading模块介绍

    与multiprocess模块在使用层面上的接口相似。

    二。开启线程的两种方式

    from threading import Thread
    def func(name):
        print("my name is %s"%name)
    if __name__ == "__main__":
        t = Thread(target=func,args="张三")
        t.start()
    
    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('egon')
        t.start()
        print('主线程')

    三。在一个进程下,开启多线程和多进程的区别

    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
        主线程
        '''
    
        #在主进程下开启子进程
        p=Process(target=work)
        p.start()
        print('主进程')
        '''
        打印结果:
        主进程
        hello
        '''
    线程的开启速度更快
    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())
    主进程下开启多线程(与主进程pid相同),开启多进程(与主进程pid不同)
    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,因为同一进程内的线程之间共享进程内的数据
    同一进程内的线程共享该进程的数据,进程间数据相互独立

    四。练习

    练习一:

    #_*_coding:utf-8_*_
    #!/usr/bin/env python
    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()
    多线程并发的socket服务端
    #_*_coding:utf-8_*_
    #!/usr/bin/env python
    
    
    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)
    客户端

    练习二:三个任务,一个接收用户输入,一个将用户输入的内容格式化成大写,一个将格式化后的结果存入文件

    from threading import Thread
    msg_l=[]
    format_l=[]
    def talk():
        while True:
            msg=input('>>: ').strip()
            if not msg:continue
            msg_l.append(msg)
    
    def format_msg():
        while True:
            if msg_l:
                res=msg_l.pop()
                format_l.append(res.upper())
    
    def save():
        while True:
            if format_l:
                with open('db.txt','a',encoding='utf-8') as f:
                    res=format_l.pop()
                    f.write('%s
    ' %res)
    
    if __name__ == '__main__':
        t1=Thread(target=talk)
        t2=Thread(target=format_msg)
        t3=Thread(target=save)
        t1.start()
        t2.start()
        t3.start()
    View Code

    五。线程相关的其他方法

    Thread实例对象的方法:

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

    threading模块提供的一些方法:

    threading.currentThread()   返回当前 的线程变量 
    threading.enumerate()       返回一个包含正在运行的线程list,
    threading.activeCount()     返回正在运行的线程数量
    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
        '''
    View Code
    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=('egon',))
        t.start()
        t.join()
        print('主线程')
        print(t.is_alive())
        '''
        egon say hello
        主线程
        False
        '''
    主线程等待子线程结束

    六。守护线程

    无论是进程还是线程,都遵循:守护进程/线程会等待主进程/线程运行完毕后被销毁。

    运行完毕:对主进程来说,运行完毕指的是  主进程代码运行完毕。

           对主线程来说,运行完毕指的是  主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕。

    详细解释:

    1.主进程在其代码结束后已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束。

    2.主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收),因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

    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=('egon',))
        t.setDaemon(True) #必须在t.start()之前设置
        t.start()
    
        print('主线程')
        print(t.is_alive())
        '''
        主线程
        True
        '''
    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    
    t1=Thread(target=foo)
    t2=Thread(target=bar)
    
    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")

    七。Python GIL

    全局解释器锁

    八。同步锁

    九。死锁现象与递归锁

    十。信号量Semaphore

    十一。Event

    十二。条件Condition(了解)

    十三。定时器

    十四。线程queue

    十五。python标准模块--concurrent.futures

  • 相关阅读:
    函数
    文件的基本操作
    c语言程序设计案例教程(第2版)笔记(一)—零散、输入输出、最小公倍数、选择排序、冒泡排序
    c语言中的rand()函数用法
    c语言 error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
    Python之列表生成式、生成器
    Python之迭代器
    Python之装饰器
    Linux之线程相关命令及常用命令
    重写、重构、重载区别
  • 原文地址:https://www.cnblogs.com/yizhixiaowenzi/p/12284376.html
Copyright © 2011-2022 走看看