Python多线程学习(一)

本文深入探讨了Python中的进程和线程,包括它们的基本概念、关系、创建方式以及特性。通过示例代码展示了如何创建和管理线程,如守护线程、线程同步(线程锁、递归锁)的应用。此外,还提到了线程安全问题,强调了线程锁在多线程编程中的重要性。
摘要由CSDN通过智能技术生成

进程和线程理解

1、线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
2、一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
3、进程之间相互独立,但一个进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程中不可见。
4、调度和切换:线程上下文切换比进程上下文切花要快的多

下面给出一个示例

import threading
import time

def test(x):
    print(x)
    time.sleep(2)


t1 = threading.Thread(target=test,args=(1,))  #创建一个线程
t2 = threading.Thread(target=test,args=(2,))
t1.start()
t2.start()


class MyThread(threading.Thread):
    def __init__(self,n):
        super(MyThread, self).__init__()
        self.n = n


    def run(self):
        print("以类的方式创建多线程",self.n)

m1 = MyThread(111)
m2 = MyThread(222)

m1.start()
m2.start()

在这里插入图片描述

线程的特性

1、守护线程
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。
2、线程中的一些方法
join方法
这个方法的意义是,当该线程使用这个方法时,如果该线程没有完成,则其他的线程必须要等到这个线程结束之后才能够开始
current_thread方法
查看我们当前运行的是什么线程
在这里插入图片描述
active_count方法
这个方法可以查看当前存活、活动着的线程数量

下面给出例子

import threading
import time
def run(x):
    print(f"线程{x}")
    time.sleep(2)


if __name__ == '__main__':
    start_time = time.time()
    res = []   #字典方便存放数据
    for i in range(50):
        # if i == 9:
        #     i = 2
        t = threading.Thread(target=run,args=(i,))
        t.setDaemon(True)   #守护线程
        t.start()
        res.append(t)   #将线程添加到字典中
        # 查看活动的线程
        print(threading.active_count())


    for t in res:   #遍历字典中的线程
        t.join()    




    # t1 = threading.Thread(target=run,args=(1,))
    # t2 = threading.Thread(target=run, args=(2,))
    # t1.start()
    # t1.join()  #等待一个线程结束用join函数
    # t2.start()

#     for i in range(50):
#         t = threading.Thread(target=run,args=(i,))
#         t.start()
#     end_time = time.time()
#
#
#  #1970年到现在总共走了多少秒
# print(time.time())
#
# # run(1)
# # run(2)
    print(f"程序共运行了{time.time()-start_time}秒")

    #查看当前线程
    print(threading.current_thread())

在这里插入图片描述
这里存活的线程有51个是因为,MyThread也是一个线程,是主线程,上面有50个线程,相加为51.

线程锁

线程锁是线程安全中十分重要的一个环节,如果没有线程锁会发生,两个线程互相抢占CPU资源,一个线程对全局变量做了++操作之后,还没来得及比较输出操作,另一个线程抢占CPU,进行比较打印输出,造成一些影响。

下面给出一个示例

import threading

def run():
    global x
    lock.acquire()   #申请一把锁
    x +=1
    lock.release()   #释放一把锁


if __name__=='__main__':
    x = 0
    res = []
    lock = threading.Lock()  #实例化线程锁
    for i in range(100):
        t = threading.Thread(target=run,args=())
        t.start()
        res.append(t)

        for t in res:
            t.join()

        print(x)

在这里插入图片描述

递归锁

当有多把锁的时候,是无法很好的判断出要释放哪个锁,所以会出现线程卡死的现象,这种情况下,就需要我们的嵌套锁了

嵌套锁的概念

在这里插入图片描述
给出个示例

import threading


def run1():
    global x
    lock.acquire()  # 申请一把锁,锁2
    x +=1
    lock.release()  # 释放一把锁,锁2
    return x


def run2():
    global y
    lock.acquire()  # 申请一把锁
    y += 1
    lock.release()  # 释放一把锁
    return y


def run3():
    lock.acquire()  # 申请一把锁,锁1
    res1 = run1()
    res2 = run2()
    lock.release()  # 释放一把锁,锁1
    print(res1,res2)


if __name__=='__main__':
    x = 0
    y = 0
    lock = threading.RLock()  #嵌套锁
    for i in range(50):
        t = threading.Thread(target=run3)
        t.start()

        while threading.active_count() != 1:   #  当有子线程在运行的时候,就不向下走,等线程都结束,再继续向下走
            print(f'正在运行{threading.active_count()}个线程')

        print('程序运行结束')

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python多线程是一种并发编程技术,可以同时执行多个线程,以提高程序的运行效率。在Python中,可以使用`threading`模块来实现多线程。 下面是一个简单的Python多线程示例: ```python import threading def worker(): print("Worker is running") # 创建线程对象 thread1 = threading.Thread(target=worker) thread2 = threading.Thread(target=worker) # 启动线程 thread1.start() thread2.start() # 等待所有线程结束 thread1.join() thread2.join() ``` 在上面的示例中,我们定义了一个`worker`函数,它会在控制台输出一条消息。然后我们创建了两个线程对象,并使用`start()`方法启动它们。最后,我们使用`join()`方法等待所有线程结束。 需要注意的是,多线程Python中并不一定能够实现真正的并行执行,因为Python的GIL(全局解释器锁)机制限制了多线程的执行效率。这意味着即使在多个线程中同时执行相同的代码,也只有一个线程可以获得CPU资源进行执行。但是,Python多线程对于某些特定的任务仍然是非常有用的,例如I/O密集型任务或者使用多核CPU的系统。 在Python学习多线程时,需要了解以下几点: 1. 线程的创建和启动:需要使用`Thread`类来创建线程对象,并使用`start()`方法来启动线程。 2. 线程的同步:由于GIL机制的存在,Python多线程并不能实现真正的并行执行。因此,需要使用锁、条件变量等机制来保证线程之间的同步和通信。 3. 线程池:可以使用线程池来管理多个线程,以提高程序的运行效率。Python中的`queue`模块提供了线程安全的队列,可以用于实现线程池。 4. 多进程:如果需要更高效的并发编程,可以使用Python的多进程模块`multiprocessing`。它可以更好地利用多核CPU的优势,并避免GIL的影响。 5. 锁的使用:在使用多线程时,需要使用锁来保证线程之间的同步和通信。需要注意避免死锁和竞争条件等问题。 6. 死锁问题:死锁是线程之间相互等待资源导致的问题,可以通过适当的调度策略和使用锁来避免死锁问题的发生。 7. 多线程的优点和缺点:多线程适用于I/O密集型任务和需要并发执行的任务。但是,它也存在一些缺点,如性能开销、资源竞争等问题。需要根据具体的应用场景来选择是否使用多线程。 总之,Python多线程是一种重要的并发编程技术,可以用于提高程序的运行效率。在学习Python多线程时,需要了解其基本原理和常见问题,并根据具体的应用场景来选择是否使用多线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值