进程与线程学习

多线程

t=threading.Thread(target=task,arge=(11,))
start()开始
join()等待

主线程在默认情况下会等待所有非守护线程(子线程)结束后才会结束程序。也就是说,如果主线程在结束前没有调用所有子线程的 join() 方法,主线程将继续执行,并且当主线程完成它的执行后,它将等待所有子线程结束。

多线程对同一个变量操作时可能造成数据竞争

python 复制代码
import threading
loop=1000000
number=0
def _add(count):
    global number
    for i in range(count):
        number+=1
def _sub(count):
    global number
    for i in range(count):
        number-=1
t1=threading.Thread(target=_add,args=(loop,))
t2=threading.Thread(target=_sub,args=(loop,))
t1.start()
t2.start()
t1.join()
#t2.join()
print(number)

未调用 t2.join() 会导致在 t1 线程结束后,主线程打印 number 的值,然后程序依然会等 t2 线程结束。但由于打印 number 的操作在 t2 结束前可能被执行,这会导致 number 的值不确定。

解决方案:
加锁
python 复制代码
import threading
loop=1000000
number=0
lock_object=threading.RLock()
def _add(count):
    lock_object.acquire() #申请锁
    global number
    for i in range(count):
        number+=1
    lock_object.release() # 释放锁
def _sub(count):
    lock_object.acquire()
    global number
    for i in range(count):
        number-=1
    lock_object.release()
# 也可以这么写
def sub():
    with lock_object:  #自动进行申请和释放
         global number
    for i in range(count):
        number-=1
t1=threading.Thread(target=_add,args=(loop,))
t2=threading.Thread(target=_sub,args=(loop,))
t1.start()
t2.start()
t1.join()
t2.join()
print(number)
Lock(同步锁)和 RLock(递归锁)区别

Lock效率更高,但是不支持多次锁的情况,一般项目开发还是用RLock

python 复制代码
import threading
lock_object=threading.RLock()
 # personA create a function
def fun():
     with lock_object:
         pass
# personB,too and use A' fun()
def run():
    print("other use")
    fun()
    print("other use")
# personC create functions,need lock,use fun
def progress():
    with lock_object:
        print('other use')
        fun()
        print('hhhhh')
死锁
竞争资源
python 复制代码
import threading
lock=threading.RLock()
num=0
def task():
    print('start')
    lock.acquire()
    lock.acquire()
    global num
    for i in range(100000):
        num+=i
    lock.release()
    lock.release()
    print(num)
for i in range(2):
    t=threading.Thread(target=task)
    t.start()
# start
# 4999950000
# start
# 9999900000
彼此通信
python 复制代码
import threading
import time
lock_1=threading.RLock()
lock_2=threading.RLock()
def task1():
    lock_1.acquire()
    time.sleep(1)
    lock_2.acquire()
    print(11)
    lock_2.release()
    print(1111)
    lock_1.release()
    print(111111)
def task2():
    lock_2.acquire()
    time.sleep(1)
    lock_1.acquire()
    print(22)
    lock_1.release()
    print(2222)
    lock_2.release()
    print(222222)
t1=threading.Thread(target=task1)
t1.start()
t2=threading.Thread(target=task2)
t2.start()

t.daemon=true 设置守护线程

name=threading.current_thread().getName() 获取当前线程名称

t.setName('xxx') 设置线程名称,要在 start()之前

线程池

相关推荐
_Kayo_16 分钟前
node.js 学习笔记3 HTTP
笔记·学习
桦说编程3 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen3 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
CCCC13101633 小时前
嵌入式学习(day 28)线程
jvm·学习
没有bug.的程序员3 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋4 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
星星火柴9364 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头4 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端