查看进程的id、队列的使用(Queue)、解决进程之间数据隔离问题(队列)、生产者消费者模型(重要)、线程相关

文章介绍了Python中查看进程ID的方法,展示了如何创建和管理子进程,以及使用队列进行进程间通信。讨论了队列的数据结构和操作,如入队、出队,并给出了不同场景下的生产者消费者模型示例。同时,文章还对比了进程和线程的特性,并提供了开启线程和多线程的代码示例。
摘要由CSDN通过智能技术生成

一、查看进程的id

'''
进程都有几个属性:进程名、进程id(pid --> process id)

每一个进程都有一个唯一的id号,通过这个id号就能找到这个进程

Linux -----> 杀进程 -----> kill -9 1001 -----> pkill 进程名

'''

import os
import time

from multiprocessing import Process


def task():
    print('task中的子进程号:', os.getpid())  # 21716
    print('主进程中的进程号:', os.getppid())  # 3420
    time.sleep(5)


if __name__ == '__main__':
    p = Process(target=task, )
    p.start()

    查看子进程p的进程号
    print('子进程的进程号:', p.pid)  # 21716

    查看主进程的进程号
    '''os.getgid()这一句写在哪个进程下,输出的就是这个进程的进程号'''
    print('主进程的进程号:', os.getpid())  # 3420

    time.sleep(10)


二、队列的使用

"""
常见的数据结构:链表、单链表、双链表、循环链表、栈、队列、树、
二叉树、平衡二叉树、红黑树、b树、b+树、b-树、图等

队列:先进先出

"""

from multiprocessing import Queue

if __name__ == '__main__':
    """
        思考:怎么样得到一个队列呢?
        在python中,内置的有一个类,Queue
    """
    队列的大小默认很大(2147483647)
    q = Queue(3)  # 这里假如有3个


    1.如何入队
    q.put("helloworld")
    q.put("helloworld1")
    q.put("helloworld2")

    2.出队
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())

if __name__ == '__main__':
    """
        思考:怎么样得到一个队列呢?
        在python中,内置的有一个类,Queue
    """
    # 队列的大小默认很大(2147483647)
    q = Queue(3)  # 这里写3个

    '''
        put、get的参数有obj, block=True, timeout=None
    '''
***********************************************************************
    # 1.如何入队
    q.put("helloworld")
    q.put("helloworld1")
    q.put("helloworld2")

    '''若指定了block参数,当队列满的时候,放不进去的时候,就会直接报错'''
    # q.put("helloworld3", block=False)  # 报错: queue.Full

    '''若指定了timeout参数,当队列中放入数据的时候,等待3秒,如果放不进去,直接报错'''
    # q.put("helloworld3", timeout=3)

    '''往队列中放入数据的时候,放不进去直接报错'''
    # q.put_nowait('helloworld3')


    # 2.出队
    print(q.get())
    print(q.get())
    print(q.get())

    # print(q.get(block=False))  # 报错
    # print(q.get(timeout=3))  # 报错
    # q.get_nowait()  # 报错
    
    '''注意:队列中剩余的数据量,这个方法的结果有点不准确'''
    # print(q.qsize())
    # print(q.empty())  # True
    print(q.full())  # False


三、解决进程之间的数据隔离问题

def task(q):
    a = 1
    q.put('子进程写入的数据')
    q.put(a)


from multiprocessing import Process
from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(3)

    '''
        若在子进程中放入一个数据,然后在主进程中取出这个数据,
        若能取到,则说明主进程和子进程之间通信了。若不能,则说明没有通信
    '''
    p = Process(target=task, args=(q, ))
    p.start()

    '''在主进程中取出子进程写进去的数据'''
    print(q.get())
    print(q.get())

    """
        现在队列中的数据在哪里存着?在内存中存着的,当数据量很大的时候,很占用机器的内存
        
        注意:当前使用较多的消息队列有:RabbitMQ,RocketMQ,ActiveMQ、Kafka、ZeroMQ,MetaMQ
    """

四、生产者消费者模型

版本1def producer(q):
    # 让生产者生产10个
    for i in range(10):
        '''生成的东西放在哪里呢?队列里'''
        q.put('这是第%s个' % i)


def consumer(q):
    '''拿东西从哪里拿呢?也是队列中'''
    while True:
        res = q.get()
        print(res)


from multiprocessing import Process
from multiprocessing import Queue


if __name__ == '__main__':
    q = Queue(20)

    p = Process(target=producer, args=(q, ))
    p.start()

    c = Process(target=consumer, args=(q, ))
    c.start()


# 版本2:
def producer(q):
    # 让生产者生产10个
    for i in range(10):
        '''生成的东西放在哪里呢?队列里'''
        q.put('这是第%s个' % i)
    q.put(None)


def consumer(q):
    '''拿东西从哪里拿呢?也是队列中'''
    while True:
        res = q.get()
        print(res)
        '''若是有多个生产者,则不适宜用q.empty()'''
        # if q.empty():
        #     break
        if res is None:
            break



版本3def producer(q):
    # 让生产者生产10个
    for i in range(10):
        '''生成的东西放在哪里呢?队列里'''
        q.put('这是第%s个' % i)


def consumer(q):
    '''拿东西从哪里拿呢?也是队列中'''
    while True:
        res = q.get()
        print(res)
        '''若是有多个生产者,则不适宜用q.empty()'''
        # if q.empty():
        #     break
        if res is None:
            break


from multiprocessing import Process
from multiprocessing import Queue


if __name__ == '__main__':
    q = Queue(20)

    p = Process(target=producer, args=(q, ))
    p.start()

    c = Process(target=consumer, args=(q, ))
    c.start()
    '''
        不能放在这个地方:是因为:开启进程有延迟,不会立刻开起来,
        先执行主进程的代码,把None放在了队列的第一个,当消费者消费数据的时候,
        直接就结束了
    '''
    q.put(None)



版本4:多生产者、少消费者
def producer(q, name, food):
    # 让生产者生产10个
    for i in range(10):
        '''生成的东西放在哪里呢?队列里'''
        q.put('生产者:%s,生产了第%s个 %s' % (name, i, food))


def consumer(q):
    '''拿东西从哪里拿呢?也是队列中'''
    while True:
        res = q.get()
        '''若是有多个生产者,则不适宜用q.empty()'''
        # if q.empty():
        #     break
        if res is None:
            break
        print(res)


from multiprocessing import Process
from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(20)

    # 4个生产者
    p1 = Process(target=producer, args=(q, 'python', 'py'))
    p2 = Process(target=producer, args=(q, 'java', 'main'))
    p3 = Process(target=producer, args=(q, 'json', 'jjson'))
    p4 = Process(target=producer, args=(q, 'golang', 'go'))
    p1.start()
    p2.start()
    p3.start()
    p4.start()

    # 2个消费者
    c1 = Process(target=consumer, args=(q,))
    c2 = Process(target=consumer, args=(q,))
    c1.start()
    c2.start()

    # 让子进程先进行
    p1.join()
    p2.join()
    p3.join()
    p4.join()

    '''
        不能放在这个地方:是因为:开启进程有延迟,不会立刻开起来,
        先执行主进程的代码,把None放在了队列的第一个,当消费者消费数据的时候,
        直接就结束了
    '''
    q.put(None)
    q.put(None)



版本5:少生产者、多消费者
def producer(q, name, food):
    # 让生产者生产10个
    for i in range(10):
        '''生成的东西放在哪里呢?队列里'''
        q.put('生产者:%s,生产了第%s个 %s' % (name, i, food))


def consumer(q):
    '''拿东西从哪里拿呢?也是队列中'''
    while True:
        res = q.get()
        '''若是有多个生产者,则不适宜用q.empty()'''
        # if q.empty():
        #     break
        if res is None:
            break
        print(res)


from multiprocessing import Process
from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(20)

    # 2个生产者
    p1 = Process(target=producer, args=(q, 'python', 'py'))
    p2 = Process(target=producer, args=(q, 'java', 'main'))
    p1.start()
    p2.start()

    # 2个消费者
    c1 = Process(target=consumer, args=(q,))
    c2 = Process(target=consumer, args=(q,))
    c3 = Process(target=consumer, args=(q,))
    c4 = Process(target=consumer, args=(q,))
    c1.start()
    c2.start()
    c3.start()
    c4.start()

    # 等待生产者进程结束
    p1.join()
    p2.join()

    q.put(None)
    q.put(None)
    q.put(None)
    q.put(None)


五、线程相关

1.开启线程

'''
线程理论:
    进程是一个任务的执行过程,在这个过程中实际做事的是线程,线程是开在进程里面的,
    需要先有进程,再有线程,一个进程中至少有一个线程,当然,也可以有多个线程

进程是自愿分配的基本单位,线程是CPU执行的最小单位

进程和线程都是由操作系统来调度的,协程是由程序员来调度的

进程 >>> 线程 >>> 协程
资源消耗最多的 >>> 线程的资源 >>> 协程

'''
from multiprocessing import Process
from threading import Thread
import threading


def task(name, name1, age):
    print('task执行了')
    print(name)
    print(name1)
    print(age)

    print(threading.currentThread())  # <Thread(duck, started 16460)>


if __name__ == '__main__':

    """
        参数:
            group=None, target=None, name=None,
            args=(), kwargs=None, *, daemon=None
            
        修改线程名称:
        name = 'name1'
    """
    t = Thread(target=task, name='lin', args=('kevin', 'tank'), kwargs={'age': 18})

    # 设置守护线程:主线程结束,子线程也跟着结束
    # t.daemon = True

    # 开启线程
    t.start()

    # 查看线程名
    # print(t.name)  # lin

    print(123)

    # 线程的方法
    print(t.is_alive())
    print(t.getName())

    t.setName('duck')
    print(t.name)

    print(465)

    # 查看最近的线程
    print(threading.currentThread())  # <_MainThread(MainThread, started 18528)>


2.开启多线程

from threading import Thread


def task(i):
    print(i)


if __name__ == '__main__':

    tt = []

    for i in range(5):
        t = Thread(target=task, args=(i, ))
        t.start()
        # t.join()
        tt.append(t)

    for j in tt:
        j.join()

    print('开启多线程')
    print(123)

六、进程和线程之间的比较

import time

from multiprocessing import Process
from threading import Thread


def work():
    print('hello')
    time.sleep(1)


if __name__ == '__main__':

    start_time = time.time()
    # # 在主进程下开启线程
    # t = Thread(target=work)
    # t.start()
    # t.join()
    # print('主线程/主进程')
    # print('time:', time.time() - start_time)
    # # time: 1.0061957836151123


    # 在主进程下开启子进程
    p = Process(target=work)
    p.start()
    p.join()
    print('主线程/主进程')

    print('time:', time.time() - start_time)
    # time: 1.067737340927124
    '''
        执行的时间不一样,线程的时间远远小于进程的执行时间
    '''

七、修改线程的数据

def work():
    print('hello')
    global n
    n = 0


if __name__ == '__main__':

    n = 1

    # 在主进程下开启线程
    t = Thread(target=work)
    t.start()
    t.join()

    print('n=', n)  # n= 0


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值