首页 > 其他分享 >多线程

多线程

时间:2022-11-16 23:01:52浏览次数:38  
标签:__ Thread threading num 线程 print 多线程

程序同时执行多个任务

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。

  • 程序的运行速度可能加快

一、线程实现方法

  线程是CPU分配资源的基本单位。当一程序开始运行,这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程相当于一个主线程;当有多线程编程时,一个进程包含多个线程(含主线程)。使用线程可以实现程序大的开发。

  • 线程是执行单位,也是最小的资源分配单位。

(一)多线程执行程序

  • 单线程执行程序
def demo1():
    for i in range(5):
        print("demo1:",i)

def demo2():
    for i in range(5):
        print("demo2:",i)
        
if __name__ == '__main__':
    demo1()
    demo2()
  • 修改为多线程之后
import threading

def demo1():
    for i in range(5):
        print("demo1在执行:", i)

def demo2():
    for i in range(5):
        print("demo2在执行:", i)

def main():
    t1 = threading.Thread(target=demo1, name="demo1")
    t2 = threading.Thread(target=demo2, name="demo2")
    t1.start()
    t2.start()

if __name__ == '__main__':
    main()
    

(二)通过继承的方式实现

from threading import Thread


class Thread_Spider1(Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    for i in range(5):
        print("主线程:", i)

 

二、线程的常用方法

方法名称 描述
threading.current_thread() 获取当前线程对象
threading.enumerate() 获取当前线程的信息
getName() 获取线程名称
setName(name) 设置线程名称

(一)threading.current_thread()

  • 获取当前线程对象
import threading

class Thread_Spider1(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        # <Thread_Spider1(Thread-1,  started 9172)>
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        # <Thread_Spider2(Thread-2, started 1304)>
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    for i in range(5):
        print("主线程:", i)
        
-----------------------------
<Thread_Spider(Thread-1, started 7936)>
子线程1开始执行 0
<Thread_Spider2(Thread-2, started 15784)>主线程: 
子线程2开始执行 0
0
子线程1开始执行子线程2开始执行主线程: 1
 1
 1
子线程2开始执行子线程1开始执行主线程: 2
 2
 2
子线程1开始执行子线程2开始执行主线程: 3 3

 3
子线程2开始执行主线程:  44
子线程1开始执行
 4

(二)threading.enumerate()

  • 获取当前线程的信息
import threading

class Thread_Spider1(threading.Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(threading.Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    print(threading.enumerate())
    # [<_MainThread(MainThread, started 3088)>, <Thread_Spider1(Thread-1, started 9040)>, <Thread_Spider2(Thread-2, started 			6376)>]
    for i in range(5):
        print("主线程:", i)
        
---------------------------------------------------------
子线程1开始执行 0
子线程2开始执行[<_MainThread(MainThread, started 7764)>, <Thread_Spider(Thread-1, started 19600)>, <Thread_Spider2(Thread-2, started 13336)>]
主线程: 0
 0
子线程1开始执行子线程2开始执行主线程: 1
 1 
1
子线程1开始执行子线程2开始执行  主线程:2
2
 2
子线程1开始执行子线程2开始执行  3主线程:3

 3
子线程1开始执行子线程2开始执行主线程: 4
  4
4

(三)修改以及获取名称

了解即可

import threading


class Thread_Spider1(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        print("线程名称:", thread.getName())
        thread.setName("我的子线程")
        print("修改后的名称:", thread.getName())
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    print(threading.enumerate())
    for i in range(5):
        print("主线程:", i)

三、共享全局变量资源竞争

  • 多个线程同时在完成一个任务的时候发生资源竞争。
import threading

num = 100

def func1():
    for i in range(200):
        global num
        if num > 0:
            print("func1-正在输出{}".format(num))
        num -= 1

def func2():
    for i in range(200):
        global num
        if num > 0:
            print("func2-正在输出{}".format(num))
        num -= 1

def func3():
    for i in range(200):
        global num
        if num > 0:
            print("func3-正在输出{}".format(num))
        num -= 1

def start():
    t1 = threading.Thread(target=func1)
    t1.start()  
    t2 = threading.Thread(target=func2)
    t2.start()
    t3 = threading.Thread(target=func2)
    t3.start()

if __name__ == '__main__':
    start()

四、锁机制

  • 解决多线程访问全局变量的安全性问题。
  • 访问全局变量无需加锁,修改时需要加锁,修改完毕之后要释放锁。
  • 加锁步骤

  1. 创建加锁对象threading.Lock()。
  2. 加锁acquire()。
  3. 解锁release()。
import threading

num = 100

lock = threading.Lock()
def func1():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func1-正在输出{}".format(num))
        num -= 1
        lock.release()

def func2():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func2-正在输出{}".format(num))
        num -= 1
        lock.release()

def func3():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func3-正在输出{}".format(num))
        num -= 1
        lock.release()

def start():
    t1 = threading.Thread(target=func1)
    t1.start()
    t2 = threading.Thread(target=func2)
    t2.start()
    t3 = threading.Thread(target=func2)
    t3.start()

if __name__ == '__main__':
    start()

 

标签:__,Thread,threading,num,线程,print,多线程
From: https://www.cnblogs.com/LoLong/p/16897857.html

相关文章

  • tensorflow1.x——如何在python多线程中调用同一个session会话
    如何在python多线程中调用同一个session会话? 这个问题源于我在看的一个强化学习代码:​​https://gitee.com/devilmaycry812839668/scalable_agent​​ 在众多的机器学习的......
  • C#多线程(一)线程基础篇
    C#多线程(一)线程基础篇 线程基础视频已经发布到B站参考文章:《ThreadinginC#》(JosephAlbahari)https://www.albahari.com/threading/《ThreadinginC#》中文翻......
  • 多线程下带事务的删除大量数据引起的锁等待超时
    @Override@Transactional(readOnly=false,propagation=Propagation.REQUIRES_NEW)//我建议不要用这个注解,他是声明式事务粒度过大,建议用使用编程式事务,可控性......
  • 异步和多线程有什么区别
    一、异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。 多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至......
  • C#多线程之高级篇(上)
    前言抛开死锁不谈,只聊性能问题,尽管锁总能粗暴的满足同步需求,但一旦存在竞争关系,意味着一定会有线程被阻塞,竞争越激烈,被阻塞的线程越多,上下文切换次数越多,调度成本越大,显然......
  • 多线程等待
    多线程等待温故而知新,好久没有用到,突然忘记 方法一CountDownEvent类usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usi......
  • python 多进程 多线程 协程
    多进程-进程池1fromconcurrent.futuresimportProcessPoolExecutor23withProcessPoolExecutor(max_workers=10)asexecutor:4results=executor.map......
  • ActiveMQ经典的使用模式(利用多线程处理消费端)
    今天看视频,里面讲了一个经典的例子,是工作中很常用的,特此将这种模式记录下来.这个例子使用了ActiveMQ的选择器,也使用了之前学的自定义线程池.队列的使用,而且很好的利......
  • 响应式编程(反应式编程)的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)
    响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)文章目录​​响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)​​​​简介​​​​......
  • Java多线程(一)
    一.线程的生命周期及五种基本状态关于Java中线程的生命周期,首先看一下下面这张较为经典的图:   上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知......