IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> python-多任务-线程 -> 正文阅读

[系统运维]python-多任务-线程

1. 多任务的概念

? ? ? ? 就是操作系统可以同时运行多个任务,真正的并行多任务只能在多核CPU上运行,但是由于任务数量远远多于CPU的核心数量,操作系统会自动把多任务轮流调度到每个核心上执行。

单核CPU通过时间片轮转/优先级调度(操作系统的算法)实现多个任务几乎同时执行

并发:多个任务同时执行,任务数<=CPU核心数

并行:多个任务"同时"执行,任务数>CPU核心数

线程的运行是没有先后顺序的,由操作系统说了算

2. 线程-demo

import time
from threading import Thread, enumerate


def sing():
    for i in range(4):
        print("-----正在唱:菊花茶-----")
        time.sleep(0.1)


def dance():
    for i in range(6):
        print("-----正在跳舞-----")
        time.sleep(0.1)


def main():
    # 创建线程实例
    t1 = Thread(target=sing)  # 当这个函数运行完毕后,意味着子线程结束了
    t2 = Thread(target=dance)
    # 开启线程
    t1.start()  # 启动线程,让线程开始执行
    t2.start()
    while True:
        print(enumerate())
        time.sleep(0.1)
        if len(enumerate()) <= 1:
            print(enumerate())
            break


if __name__ == '__main__':
    main()

3.? 验证何时创建线程,也就是线程列表里面包含了子线程

import time
from threading import Thread, enumerate


def sing():
    for i in range(4):
        print("-----正在唱:菊花茶-----")
        time.sleep(0.1)


def main():
    # 创建线程实例
    print(enumerate())
    t1 = Thread(target=sing)  # 当这个函数运行完毕后,意味着子线程结束了
    print(enumerate())
    # 开启线程
    t1.start()  # 启动线程,让线程开始执行
    print(enumerate())


if __name__ == '__main__':
    main()

Thread()实例化一个对象的时候并不会创建线程,只有在调用线程实例的start方法时,才会真正创建线程,并执行线程。

4. 通过自定义类(继承自threading.Thread类)来实现多线程

import threading
import time


class MyThread(threading.Thread):
    """通过类实现多线程"""
    def run(self):
        """run方法执行完毕,线程结束"""
        for i in range(5):
            time.sleep(1)
            print(f"I am {self.name}")


if __name__ == '__main__':
    t1 = MyThread()
    t2 = MyThread()
    print(threading.enumerate())
    t1.start()
    t2.start()
    print(threading.enumerate())

5.? 多线程共享全局变量,但是如何避免资源竞争,互斥锁

?

import threading

num = 0


def test01():
    global num
    for x in range(1000000):
        # 上锁,如果之前没被上锁,那么此时上锁成功
        # 如果上锁之前已经被上锁了,那么会堵塞在这里,直到这个锁被解开为止
        # 上锁有一个原则,上锁的代码越少越好
        lock.acquire()
        num += 1
        # 解锁
        lock.release()


def test02():
    global num
    for x in range(1000000):
        lock.acquire()
        num += 1
        lock.release()


# 定义一个锁的全局变量
lock = threading.Lock()

if __name__ == '__main__':
    t1 = threading.Thread(target=test01)
    t2 = threading.Thread(target=test02)

    t1.start()
    t2.start()

    t1.join()
    t2.join()
    print(num)

6.? 死锁

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

import time
import threading


class MyThread1(threading.Thread):
    def run(self):
        MutexA.acquire()
        print(self.getName(), "----do1--up----")
        time.sleep(1)

        MutexB.acquire()
        print(self.getName(), "----do1--down----")
        MutexB.release()

        MutexA.release()


class MyThread2(threading.Thread):
    def run(self):
        MutexB.acquire()
        print(self.getName(), "----do2--up----")
        time.sleep(1)

        MutexA.acquire()
        print(self.getName(), "----do2--down----")
        MutexA.release()

        MutexB.release()


# 创建两个互斥锁
MutexA = threading.Lock()
MutexB = threading.Lock()


def main():
    t1 = MyThread1()
    t2 = MyThread2()
    t1.start()
    t2.start()
    t1.join()
    t2.join()


if __name__ == '__main__':
    main()

避免死锁:

(1)程序设计时要尽量避免(银行家算法)

(2)添加超时时间

7. 多线程-udp聊天器

import time
import threading
import socket


def recv(tasks_socket):
    while True:
        recv_data = tasks_socket.recvfrom(1024)
        print(f"接收到的数据是:{recv_data[0].decode()}")


def send(tasks_socket, dest_ip, dest_port):
    while True:
        time.sleep(0.01)
        send_data = input("请输入要发送的数据")
        tasks_socket.sendto(send_data.encode(), (dest_ip, dest_port))


def main():
    tasks_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    tasks_socket.bind(("", 8000))

    dest_ip = input("请输入对方IP:")
    dest_port = int(input("请输入对方Port:"))

    t1 = threading.Thread(target=send, args=(tasks_socket, dest_ip, dest_port))
    t2 = threading.Thread(target=recv, args=(tasks_socket,))
    t1.start()
    t2.start()


if __name__ == '__main__':
    main()

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 11:10:24  更:2021-08-02 11:11:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 6:02:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码