Python线程

多任务

  • 概念:操作系统可以同时运行多个任务

  • 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务在同一时间段执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已)

  • 并行:指的是多核cpu情况下,多个任务的一些任务往往在同一时间点执行

线程

  • 概念:就是一个进程内部的一条代码执行流程

  • 默认存在的就是主线程,新创建出来的叫做子线程

创建线程

使用threading模块 或继承threading.Thread

  • target 指定线程执行的函数名

  • args 指定函数的参数

  • enumerate() 查看当前进程中的线程列表

  • join() 主线程等待子线程执行完成后,才能继续往下运行

多线程共享全局变量,如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确

同步:就是协同步调,按预定的先后次序进行运行

互斥锁

  • 概念:某个线程要更改共享资源时,先将其锁定,此时资源的状态为"锁定",其他线程不能更改;直到该线程释放资源,将资源的状态变成"非锁定",其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性

创建使用互斥锁

# 创建锁
mutex = threading.Lock()
#  锁定
mutex.acqire()
# 释放
mutex.release()

优缺点

优点:确保某段关键代码只能有一个线程从头到尾完整的执行

缺点:

  • 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率大大的下降了

  • 由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁

死锁

  • 概念:在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁

主要原因

  • 没有正确释放

  • 资源分配不当

避免死锁

  • 程序设计时要尽量避免

  • 附加超时 时间等

线程实现简单的多任务聊天程序

import socket
import threading


def send_msg(udp_socket):
    """获取输入数据,并将其发送给对方"""
    msg_num = input("请输入要发送的数据:")
    dest_ip = input("请输入对方ip地址:")
    dest_port = int(input("请输入对方端口号:"))
    udp_socket.sendto(msg_num.encode(), (dest_ip, dest_port))


def recv_msg(udp_socket):
    """循环接收并显示数据"""
    while True:
        recv_msug, recv_ip = udp_socket.recvfrom(1024)
        print("接收到%s的数据:%s" % (str(recv_ip), recv_msug.decode("gbk")))


def main():
    # 创建套接字
    udp_socekt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定端口
    udp_socekt.bind(("", 6666))

    # 创建一个子线程(收数据)
    recv_thd = threading.Thread(target=recv_msg, args=(udp_socekt,))
    recv_thd.start()

    while True:
        # 选择功能
        print("=" * 30)
        print("1.发送消息")
        print("2.接收消息")
        print("3.退出")
        print("=" * 30)
        op_num = input("请输入你要进行的操作:")
        if op_num == "1":
            send_msg(udp_socekt)
        # elif op_num == "2":
            # recv_msg(udp_socekt)
        elif op_num == "3":
            print("欢迎下次使用")
            break
        else:
            print("输入有误!请重新输入")


if __name__ == '__main__':
    main()
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 线程状态新建,就绪,运行,阻塞,死亡。 线程同步多线程可以同时运行多个任务,线程需要共享数据的时候,可能出现数据不...
    KevinCool阅读 4,202评论 0 0
  • 线程的定义 线程是操作系统能够进行运算调度的最小单位。它被包含在进程中。是进程中的实际运作单位。一条线程指的是进程...
    So_ProbuING阅读 2,682评论 0 0
  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。我们前面提到了进程是由若干线程组成的,一个进程至少有一个线...
    壁花烧年阅读 4,231评论 0 0
  • 在上篇中,我们已经讨论过如何去实现一个 Map 了,并且也讨论了诸多优化点。在下篇中,我们将继续讨论如何实现一个线...
    一缕殇流化隐半边冰霜阅读 12,278评论 5 41
  • 去年10月份,换了一份行政的工作。朝九晚五,很轻松。于是想要不准备一下司考,这是我多年的心愿,之前迫于生计...
    春暖雁归阅读 952评论 0 1