Python_07

多线程

1、线程:
线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

2、创建线程的目的是什么?

是为了建立程序单独的执行路径,让多部分代码实现同时执行。也就是说线程创建并执行需要给定线程要执行的任务。

3、多线程的特点:
1.本质上是异步的
2.需要多个并发活动
3.每个活动的处理顺序可能是不确定的,或者说是随机的、不可预测的。

4、多线程运行有如下优点:
1.使用线程可以把占据长时间的程序中的任务放到后台去处理。
2.用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
3.程序的运行速度可能加快
4.在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

5、线程的退让:
在其他线程正在运行时,线程可以暂时搁置(也称为睡眠)。
线程可以被抢占(中断)。

6、线程的生命周期
在这里插入图片描述各个状态说明:

New新建 :新创建的线程经过初始化后,进入Runnable状态。
Runnable就绪:等待线程调度。调度后进入运行状态。
Running运行:线程正常运行
Blocked阻塞:暂停运行,解除阻塞后进入Runnable状态重新等待调度。
Dead消亡:线程方法执行完毕返回或者异常终止。

1、主线程和小弟线程:

import _thread   # 多线程
import win32api

def show(i):
    # 0 代表系统,你真帅代表内容,来自JOKER代表标题,0代表窗口类型0,1,2,3
    mystr = win32api.MessageBox(0,"你真帅","来自tzx的问候",0)


for i in range(5):   # 这是小弟线程
    _thread.start_new_thread(show,(i,))  # 前面是执行函数,后面是一个元组,可以不写前提是函数没有形参


while True:  # 在这里加入死循环是为了脚本主线程不死,小弟线程才能运行
    pass

运行结果:
在这里插入图片描述

2、多线程速度:

import _thread
import time
def go():
    for i in range(5):
        print(i,"-------")
        time.sleep(1)

for i in range(5):   # 同时执行5次
    _thread.start_new_thread(go,())

for j in range(6): # 让主线程卡顿6秒
    time.sleep(1)

print("over")

#运行结果:
0 -------
0 -------
0 -------
0 -------
0 -------
1 -------
1 -------
1 -------
1 -------
1 -------
2 -------
2 -------
2 -------
2 -------
2 -------
3 -------
3 -------
3 -------
3 -------
3 -------
4 -------
4 -------
4 -------
4 -------
4 -------
over

3、线程冲突:

import _thread

num = 0
def add():
    for _ in range(1000000):
        global num
        num += 1
    print(num)

for i in range(5):
    _thread.start_new_thread(add,())
# 这里就是线程冲突,5个线程同时抢夺num的资源,导致最后结果错误

while True:  # 防止主线程不死
    pass


#运行结果:
1098897
1291896
994196
1205990
1327516

4、基于类实现多线程:

import threading
import win32api


class Mythread(threading.Thread):   # 继承threading.Thread类
    def run(self):  # 重写threading.Thread类中的run函数
        win32api.MessageBox(0,"hello",'tzx',0)


for i in range(2):  # 同时创建5个线程
    t = Mythread()  # 初始化
    t.start()  # 开启


while True:
    pass

运行结果:
在这里插入图片描述
5、类线程顺序风格:

import threading
import win32api


class Mythread(threading.Thread):   # 继承threading.Thread类
    def run(self):  # 定义函数
        win32api.MessageBox(0,"hello",'tzx',0)


for i in range(5):
    t = Mythread()  # 初始化
    t.start()  # 开启
    # 等待一个线程执行完毕,再执行下一个线程,一方面可以阻止脚本主线程死掉,另一方面也可以防止线程冲突的一种办法
    t.join()
# t.join() 如果将其放在外部的不确定因素是,系统给for 循环和下面的代码锁定了一片内存,当循环执行完成之后,
# 内存就开锁了,但是里面的东西还依然存在,所以才结束一个窗体,game over就出来了,
# 就和删除文件后,内存中可能还有文件一样的道理

print("game over")

6、类线程的乱序风格:

import threading
import win32api


class Mythread(threading.Thread):  # 继承threading.Thread类
    def __init__(self, num):
        threading.Thread.__init__(self)  # 父类初始化
        self.num = num

    def run(self):  # 定义函数
        win32api.MessageBox(0, "hello" + str(self.num), 'joker', 0)
        print(self.getName())  # 获取线程名


Mythd = []
for i in range(5):
    t = Mythread(i)  # 初始化
    print(i)
    t.start()  # 开启
    Mythd.append(t)  # 将乱序线程(同时抢夺run这个函数)加入列表

for j in Mythd:
    # 这里与顺序不同,上面显示所有的线程都加入Mthd列表(所以一次性跳出5个窗口,但是主线程还没死,因为有join卡住)。
    # j是线程
    j.join()  # 这里主线程同时等待所有线程都执行完毕,才执行“game over”
print("game over")

#运行结果:
0
1
2
3
4
Thread-4
Thread-2
Thread-1
Thread-5
Thread-3
game over

7、Rlock避免死锁:

import threading

num = 0
mutext = threading.RLock()  # PLOCK避免单线程死锁


class Mythreading(threading.Thread):
    def run(self):
        global num
        if mutext.acquire(1):
            num += 1
            print(self.name, num)
            if mutext.acquire(1):
                num += 1000
                mutext.release()

            mutext.release()


for i in range(5):  # 开启5个进程
    t = Mythreading()
    t.start()


#运行结果:
Thread-1 1
Thread-2 1002
Thread-3 2003
Thread-4 3004
Thread-5 4005

8、信号限制线程数量:

import threading

import time

sem = threading.Semaphore(2)  # 限制最大线程数为2个
def gothread():
    with sem:  # 锁定数量
        for i in range(10):
            print(threading.current_thread().name, i)  # 打印线程名字
            time.sleep(1)


for i in range(5):
    threading.Thread(target=gothread).start()  # 乱序执行多线程,就可以考虑为有些cpu牛逼些能够执行快一点


#运行结果:
Thread-1 0
Thread-2 0
Thread-1 1
Thread-2 1
Thread-1 2
Thread-2 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值