首页 > 其他分享 >线程同步(线程锁)

线程同步(线程锁)

时间:2022-09-24 17:24:19浏览次数:58  
标签:__ 同步 Thread list1 threading 线程 当前

多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)但是当线程需要共享数据时,可能存在数据不同步的问题。为了避免这种情况,引入了锁的概念。

1 lock = threading.Lock()
2 lock.acquire()  # 请求得到锁
3 lock.release()  # 释放锁
4 只要不释放其他的线程都无法进入运行状态

 

1、初始程序:

import threading
import random
import time

lock = threading.Lock()

list1 = [0] * 10  # [0,0,0,0,0,0,0,0,0,0]


def task1():
    for i in range(len(list1)):
        list1[i] = 1    # random.randint(1, 100)
        time.sleep(0.5)
        print(list1)


def task2():
    for i in range(len(list1)):
        print(f'当前的值是{i}')
        time.sleep(0.5)


if __name__ == '__main__':
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task2)

    t1.start()
    t2.start()

运行结果:

当前的值是0
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
当前的值是1
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
当前的值是2
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
当前的值是3
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
当前的值是4
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
当前的值是5
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
当前的值是6
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
当前的值是7
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0]
当前的值是8
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
当前的值是9
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

进程已结束,退出代码0

 

 

2、程序加锁:

 1 import threading
 2 import random
 3 import time
 4 
 5 lock = threading.Lock()
 6 
 7 list1 = [0] * 10  # [0,0,0,0,0,0,0,0,0,0]
 8 
 9 
10 def task1():
11     lock.acquire()    # 请求得到锁
12     for i in range(len(list1)):
13         list1[i] = 1    # random.randint(1, 100)
14         time.sleep(0.5)
15         print(list1)
16     lock.release()    # 释放锁
17 
18 
19 def task2():
20     # 获取线程锁,如果已经上锁,则等待锁的释放
21     lock.acquire()
22     for i in range(len(list1)):
23         print(f'当前的值是{i}')
24         time.sleep(0.5)
25     lock.release()
26 
27 
28 if __name__ == '__main__':
29     t1 = threading.Thread(target=task1)
30     t2 = threading.Thread(target=task2)
31 
32     t1.start()
33     t2.start()

运行结果:

[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
当前的值是0
当前的值是1
当前的值是2
当前的值是3
当前的值是4
当前的值是5
当前的值是6
当前的值是7
当前的值是8
当前的值是9

进程已结束,退出代码0

 

死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。尽管死锁很少发生,但一旦发生就会造成应用的停止响应,程序不做任何事情。   为什么会产生死锁? 1.因为系统资源不足。 2.进程运行推进的顺序不合适。    3.资源分配不当   例如:      死锁是因为多线程访问共享资源,由于访问的顺序不当所造成的,通常是一个线程锁定了一个资源A,而又想去锁定资源B;在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿释放自己的资源,造成两个线程都在等待,而无法执行的情况。   死锁案例:
 1 from threading import Thread, Lock
 2 import time
 3 
 4 lockA = Lock()
 5 lockB = Lock()
 6 
 7 
 8 class MyThread1(Thread):    # 自定义线程
 9     def run(self):
10         if lockA.acquire():
11             print(f"{self.name}获取了A锁....")
12             time.sleep(0.1)
13 
14             if lockB.acquire(timeout=5):    # 超时自动释放锁,自动调用 release()
15                 print(f"{self.name}又获取了B锁,原程序中还有A锁")
16                 lockB.release()
17 
18             lockA.release()
19 
20 
21 class MyThread2(Thread):
22     def run(self):
23         if lockB.acquire():
24             print(f"{self.name}获取了B锁....")
25             time.sleep(0.1)
26 
27             if lockA.acquire(timeout=5):    # 超时自动释放锁,自动调用 release()
28                 print(f"{self.name}又获取了A锁,原程序中还有B锁")
29                 lockA.release()
30 
31             lockB.release()
32 
33 
34 if __name__ == '__main__':
35     t1 = MyThread1()
36     t2 = MyThread2()
37 
38     t1.start()
39     t2.start()

原运行结果:

解决死锁后的运行结果:

Thread-1获取了A锁....
Thread-2获取了B锁....
Thread-1又获取了B锁,原程序中还有A锁

进程已结束,退出代码0
  产生死锁的条件有四个: 1.互斥条件:所谓互斥就是进程在某一时间内独占资源。 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。 4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 只要破坏了一个必要条件,那么我们的死锁就解决了

标签:__,同步,Thread,list1,threading,线程,当前
From: https://www.cnblogs.com/dudu-/p/16725042.html

相关文章

  • 线程和进程的关系?js为什么是单线程的?
    一、线程是包含在进程中的,线程其实就是一个指令序列,如果加上计算机分配给它的资源(如内存等)之后就是一个进程。二、可以设想一个场景,js适用于多线程,如果几个线程同时对一个......
  • Python使用事件循环创建线程池和进程池
    1、来源参考参考官方文档示例:https://docs.python.org/3.9/library/asyncio-eventloop.html#asyncio.loop.run_in_executor2、代码示例1#-*-coding:utf-8-*-2......
  • Ubuntu 进程 线程 查看 设置(top taskset)
    目录toptop详解及使用top常用的命令tasksettaskset的基本使用1.显示某个进程(线程)运行所在的核2.设置某个进程(线程)运行的核top主要用于查看Linux系统中的所有......
  • 如何优雅转换且避免线程不安全的问题
    一、常见时间格式化方式publicstaticvoidmain(String[]args){Datenow=newDate();//创建一个Date对象,获取当前时间StringstrDateFormat="yyyy-MM......
  • monstache 实时同步mongodb 数据到 elasticsearch
    最近在做数据统计功能,需要将mongodb数据实时同步到 elasticsearch中。目前找到的方案有两种1、通过flinkmongodbcdc flinkmongodbcdc的优点是比较灵活,可以将mong......
  • UEC++ 多线程(一) FRunnable
    虚幻官方文档:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/HAL/FRunnable/FRunnable“runnable”对象的接口。可运行对象是在任意线程上“运行”的对象......
  • 线程池
    Java内置线程池线程池有几个核心参数:1、核心线程数2、最大线程数3、阻塞队列1、线程池创建时,不会创建线程。2、当有任务到来时,如果当前执行线程数少于核心线程数,会......
  • 【代码片段】Qt6.2.4 QProcess使用(打开外部程序,运行命令,同步、阻塞方式)
    参考https://blog.csdn.net/qq_38232598/article/details/100745552https://www.cnblogs.com/lsgxeva/p/12641707.htmlQProcess类QProcess类是Qt中专门用于启动一个......
  • 使用Typro高效编写并同步博客
    使用Typro高效编写并同步博客一.前言写博客,可以带给我们很多好处,比如可以让我们结识更多志同道合的人;在写博客过程中去查技术资料或者实践可以让我们对知识的掌握和理解......
  • 尚硅谷大数据项目之电商数仓(3数仓数据同步策略)
    尚硅谷大数据项目之电商数仓(3数仓数据同步策略)(作者:尚硅谷研究院) 版本:V5.0 第1章实时数仓同步数据实时数仓由Flink源源不断从Kafka当中读数据计算,所以不需要手动同......