锁在IT界都是非常重要的,不单单只有在Python中出现,尤其是数据库中的锁更多。比如:表锁、行锁、悲观锁、乐观锁、进程锁、互斥锁、递归锁、可重入锁、死锁、等···
当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。
from multiprocessing import Process # 导入进程模块
import time # 导入时间模块
def index(i): # 创建一个函数来作为子进程执行代码
print(f'进程{i}进来了')
time.sleep(1)
print(f'进程{i}离开了')
if __name__ == '__main__': # 进程必须在__name__ 中运行
for i in range(5): # 循环执行子进程5次
p = Process(target=index, args=(i+1,)) # 实例化执行对象
p.start() # 开始执行进程
# 打印结果:
进程1进来了
进程2进来了
进程5进来了
进程3进来了
进程4进来了
进程2离开了进程1离开了
进程3离开了进程4离开了
进程5离开了
由并发变成了串行,牺牲了运行效率,但避免了竞争
from multiprocessing import Process, Lock # 导入进程模块和进程锁模块
import time # 导入时间模块
def index(i, lock):
lock.acquire() # 上锁
print('进程%s进来' % i)
time.sleep(1)
print('进程%s离开' % i)
lock.release() # 解锁
if __name__ == '__main__':
lock = Lock()
for i in range(5):
p = Process(target=index, args=(i + 1, lock))
p.start()
打印结果
进程2进来
进程2离开
进程3进来
进程3离开
进程1进来
进程1离开
进程5进来
进程5离开
进程4进来
进程4离开
import time, os
from multiprocessing import Process
def index():
print('index的子进程号:', os.getpid())
print('查看index子进程的父进程号:', os.getppid())
time.sleep(5)
if __name__ == "__main__":
p = Process(target=index)
p.start()
print('查看子进程号:', p.pid)
print('查看主进程号:', os.getpid())
time.sleep(10)
打印结果:
查看子进程号: 11920
查看主进程号: 27780
index的子进程号: 11920
查看index子进程的父进程号: 27780
n=100
def task():
global n
n=1
print("子进程")
from multiprocessing import Process
"""这两个进程之间的数据有没有通信? 么有通信"""
if __name__ == '__main__':
p = Process(target=task)
p.start()
"""先让子进程先执行,让子进程去改值"""
p.join()
print("主进程中得值:", n)
"""问题是:如何让进程与进程之间数据通信? """
存储数据的地方,所有主进程和子进程都可以存数据或者取数据
from multiprocessing import Queue
q = Queue(3) # 括号内指定存储数据的个数,默认可以存SEM_VALUE_MAX =
#1. 往消息队列种存放数据
q.put(111)
print(q.full()) # 判断队列是否已满 False
q.put(222)
q.put(333)
print(q.full()) # 判断队列是否已满 True
#2.从消息队列取出数据
print(q.get()) # 111
print(q.empty()) # 判断队列是否为空 False
print(q.get()) # 222
print(q.get()) # 333
# print(q.empty()) # 判断队列是否为空 True
# print(q.get()) # 数据拿不到值,就会一直等着,处于阻塞态
print(q.get_nowait()) # 如果队列没有数据,会直接报错
"""full() empty() 在多进程种都不能使用,判断会出现失误,
执行q.full()是True,在极限情况,当队列满的时候,当一个进程执行q.get(),队列的数据会被拿走
执行q.empty()是true,在极限情况,队列是空的时候,你执行q.empty是空的下一秒有一个进程往里面存数据,此时的队列不是空的
,"""
rom multiprocessing import Process, Queue
def product(q, bool):
for i in range(10):
q.put('这是我生产的%s个%s' % (i + 1, bool))
def consumer(q):
while True:
res = q.get()
print(res)
if res is None:
break
if __name__ == '__main__':
q = Queue(10)
# 生产者
p1 = Process(target=product, args=(q, '包子'))
p2 = Process(target=product, args=(q, '饺子'))
p3 = Process(target=product, args=(q, '馒头'))
p4 = Process(target=product, args=(q, '鸡蛋'))
# 消费者
c = Process(target=consumer, args=(q,))
c.start()
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
p4.start()
p4.join()
q.put(None)
在一个进程中,线程就是必须存在的,至少要有一个线程来执行任务
一个进程中可以有多个线程,在一个进程中可有开启多个线程来执行任务
进程和线程都是有操作系统调度的
进程是操作系统分配资源的基本单位,线程是操作系统执行的最小单位
如何开启线程? 跟开进程是一样的
import time
def task(a, b):
print("from task")
time.sleep(2)
print("aaa")
from multiprocessing import Process
from threading import Thread
import threading
if __name__ == '__main__':
# p=Process(target=task)
# p.start()
# deamon
"""开线程的资源非常小,以至于代码走到这一行就立马开起来了,所以就会立刻执行"""
t=Thread(target=task, name='Thread-2', args=('a', ), kwargs={'b':1})
# t.setDaemon(True)
"""设置为了守护进程:主进程结束,子进程跟着结束"""
t.daemon = True # 把该线程设置为守护线程, 主线程执行完毕,子线程也结束
"""守护线程有什么用?"""
t.start()
# t.join()
# print(t.name)
"""一个进程中如果只有一个线程,该线程称之为是主线程,其他线程称之为是子线程"""
t.is_alive()
print(t.getName()) # t.name
t.setName('aaaa')
# t.name = 'aaa'
print("主线程")
print(threading.currentThread())
print(threading.enumerate())
print(threading.activeCount())