今日内容详细

进程锁

"""锁在IT界都是非常重要的,不但在Python中出现,尤其是数据库中得锁更多,比如:表锁、行锁、悲观锁、乐观锁、进程锁、互斥锁、递归锁、可重入锁、死锁等"""

# 使用锁的目的就是为了保证安全!
import time
from multiprocessing import Process, Lock
def task(i, lock):
    # 上一把锁
    lock.acquire()
    print("进程%s来了" % i)
    time.sleep(1)
    print("进程%s走了" % i)
    # 释放锁
    lock.release()
    """只要你上了锁,一定别忘了最后释放锁,否则的话,别的进程永远进不来"""
    # 加锁一定好码? 虽然保证了数据的安全,但是呢,执行的效率一定是降低了
    # 有些场景该加锁的时候一定要加锁,

if __name__ == '__main__':
    lock=Lock()  # 得到一把锁
    for i in range(3):
        p = Process(target=task, args=(i+1, lock))
        p.start()

如何查看进程号

import time
import os
from multiprocessing import Process, Lock
"""有了进程号,我们就可以通过进程号来结束进程的执行   kill 9176 kill -9 9176"""
# taskkill /pid {pid}
def task():
    print("task进程的进程号:", os.getpid()) # os.getpid() 写在哪个进程里面就会输出哪个进程的进程号
    print("task进程的父进程的进程号:", os.getppid()) # parent process
    import time
    time.sleep(20)
if __name__ == '__main__':
    p=Process(target=task, )
    p.start()

    print('子进程的进程号:', p.pid)
    print("主进程的进程号", os.getpid())
    time.sleep(10)

进程之间数据隔离问题

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)
    
"""问题是:如何让进程与进程之间数据通信? """

队列(Queue)

数据结构:链表、单链表、双链表、循环链表、栈、队列、树、二叉树、图

重点来看队列: 先进先出
栈的特点:先进后出
# 在python中如何使用队列
它给我们提供了一个内置的队列类

from multiprocessing import Queue


q=Queue(3)
## 入队:往队列里面添加数据

"""block=True, timeout=None"""
q.put('helloworld1')
q.put('helloworld2')
q.put('helloworld3')
# block=False: 如果往队列里面放数据放不进去的时候,会立马报错,报队列已满的错误信息
# q.put('helloworld4', block=False)

# timeout:超时的时间, 如果在指定的时间内,没有放进去,就会直接报错
# q.put('helloworld4',  timeout=3)

# q.put_nowait('helloworld4')


## 出队:从队列里面取出值
print(q.get())
print(q.get())
print(q.get())
# print(q.get(block=False))
# print(q.get(timeout=3))
# print(q.get_nowait())
print(q.qsize())
print(q.empty())
print(q.full())

"""现在队列里面的数据在哪里存着? 在内存中存着的"""
# 专业的消息队列:kafka, rabbitmq等专业的消息队列 他们能够解决一些特殊场景的问题

生产者消费者模型(重要)

"""在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题"""
该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度

为什么要使用生产者和消费者模式?


def producer(q, food):
    """先给我生产10个包子"""
    for i in range(10):
        q.put("生产的第%s个包子" % i)

def consumer(q):
    while True:
        res = q.get()
        print(res)
        if res is None:
            break


from multiprocessing import Process, Queue

if __name__ == '__main__':
    q = Queue(20)
    # 生产者
    p1 = Process(target=producer, args=(q,'包子'))

    p1.start()
 
    # 消费者
    c1 = Process(target=consumer, args=(q,))
 
    c1.start()
 
    """None放在这里是不行的,就想放在这里,你说怎么办?"""
    p1.join()
    p2.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())