第六天-进程与线程编程

本文详细介绍了Python中的进程和线程概念,包括进程的创建、多进程池的应用、进程锁的使用以及进程间通信。还讨论了gil全局锁对Python多线程的影响,以及异步编程(如asyncio和gevent)的使用场景和区别。
摘要由CSDN通过智能技术生成

目录

1.进程

1.进程的创建

2.进程池和进程锁

3.进程锁

4.进程的通信

2.线程

1.线程的创建

2.线程次的创建

3.Gil全局锁

4.异步的使用


1.进程

1.进程的创建

1.进程就是程序执行的载体

2.打开的每个程序,每个python脚本都是启动一个进程;

3.进程的运行就是cpu和内存

4.多进程就是同时执行多个程序

5. 进程的创建: multiprocessing模块

6.多线程的问题:

        1.通过多线程执行的模块无法获取返回值;(可以通过进程池获取)

         2.多个进程修改文件可能会出现问题;(可以使用进程锁解决)

        3.进程数量太多可能会照成资源不足,系统宕机;

import os
import time
import multiprocessing

def work_a():
    for i in range(5):
        print(i,"a","pid:",os.getpid())
        time.sleep(1)

def work_b():
    for i in range(5):
        print(i,"b","pid:",os.getpid())
        time.sleep(1)

if __name__ == '__main__':
    nowtime=time.time()
    workaPrcess=multiprocessing.Process(target=work_a)
    workbPrcess = multiprocessing.Process(target=work_b)
    for i in (workaPrcess,workbPrcess):
        i.start()
    for i in (workaPrcess, workbPrcess):
        i.join()
    print("执行时间:" , time.time()-nowtime)
    print("主线程pid:", os.getpid())

>

0 a pid: 77024
0 b pid: 76972
1 a pid: 770241 b 
pid: 76972
22  ba  pid:pid:  7702476972

3 3b  pid:a  76972pid: 77024

4 a pid: 77024
4 b pid: 76972
执行时间: 5.307990789413452
主线程pid: 79928

2.进程池和进程锁

1.进程池为了避免进程创建过多,照成系统资源不足,可以设置固定数量的进程池;

2.避免了创建与关闭的消耗;

3.进程池的创建 multiprocessing

4.可以获取返回值

import os
import time
import multiprocessing

def printcount(count):
    print("count: {} pid: {}".format(count,os.getpid()))
    time.sleep(1)
    return count,os.getpid()


if __name__ == '__main__':
    #声明5个进程池
    pool = multiprocessing.Pool(5)
    results=[]
    for i in range(20):
        result=pool.apply_async(func=printcount,args=(i,))
        results.append(result)
        
    for res in results:
        print("进程返回参数:{}".format(res.get()))

3.进程锁

1.进程锁的创建 ,同样可用于线程锁;

2.用于进程之间的阻塞

import os
import time
import multiprocessing

def printcount(count,lock):
    try:
        lock.acquire()
        print("count: {} pid: {}".format(count,os.getpid()))
        time.sleep(1)
        return count,os.getpid()
    finally:
        lock.release()

if __name__ == '__main__':
    #声明5个进程池
    pool = multiprocessing.Pool(5)
    results=[]
    #添加锁,每个进程进行阻塞
    manage= multiprocessing.Manager()
    lock=manage.Lock()
    for i in range(20):
        result=pool.apply_async(func=printcount,args=(i,lock,))
        results.append(result)

    for res in results:
        print("进程返回参数:{}".format(res.get()))

4.进程的通信

1. 进程之前的通信依赖于队列,

2. 队列的创建

import multiprocessing
import time

class Work(object):

    def __init__(self,q):
        self.q=q

    def send(self,message):
        self.q.put(message)


    def receive(self):
        while True:
            print("接受到值",self.q.get())

    def sendall(self):
        i=0
        while True:
            i += 1
            self.q.put(i)
            time.sleep(1)

if __name__ == '__main__':
    work=Work(multiprocessing.Queue())

    send=multiprocessing.Process(target=work.send,args=("你好",))
    send.start()
    receive=multiprocessing.Process(target=work.receive)
    receive.start()
    sendall = multiprocessing.Process(target=work.sendall)
    sendall.start()

    sendall.join()

2.线程

1.线程依赖于进程,现有进程才有拥有线程;通过进程的资源来执行任务

2. 一个进程总存在多个线程,称为多线程

3.正常执行的脚本就是主线程,

1.线程的创建

1.线程的问题:

       1. 通过线程执行的函数无法获取返回值

       2.多线程同时修改文件可能会照成数据错乱

import threading
import random
import time

'''
通过多线程,进行将一个list数据存放到另一个list中
'''

old_list=["1","2","3","4","5","6","7","8","9"]
new_list=[]

def work():
    #通过随机函数,随机获取放入到新list中
    item=random.choice(old_list)
    old_list.remove(item)
    new_list.append(item)
    #模拟数据执行,防止执行太快
    time.sleep(1)

if __name__ == '__main__':
    threads=[]
    nwotime=time.time()
    for i in range(len(old_list)):
        thread=threading.Thread(target=work)
        thread.setName("work-th")
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()
    print("old_list:",old_list)
    print("new_list:", new_list)
    print("执行时间:",(time.time()-nwotime))

old_list: []
new_list: ['7', '5', '6', '9', '2', '3', '8', '4', '1']
执行时间: 1.0147948265075684

2.线程次的创建

from concurrent.futures import ThreadPoolExecutor
import time
from multiprocessing  import Manager


def work(i,lock):
    lock.acquire()
    try:
        print("i:",i)
        time.sleep(1)
        return i
    finally:
        lock.release()

if __name__ == '__main__':
    tPool= ThreadPoolExecutor(2)
    threads=[]
    #添加锁阻塞线程
    lock=Manager().Lock()
    for i in range(20):
        thread=tPool.submit(work,i,lock)
        threads.append(thread)

    for thread in threads:
        print(thread.result())

3.Gil全局锁

1. 在python中保留的Gil锁,

2.在其他语言中,主进程会自动寻找空闲的线程;

3.在python中定义了一个进程,只会在一个线程中执行,不会寻找有空闲的线程执行;

1. python的多线程只会在一个线程中执行

2.为了保留线程的安全

3.可以使用pypy可去掉Gil线程锁

4.可以通过多进程和多线程解决

4.异步的使用

1. 异步与多线程多进程的区别

        1.异步也是一个线程,属于轻量级的线程;“协程”

        2.可以通过异步获取返回值;

        3.主进程需要异步才行,所有程序都是异步才可进行执行;

        4.更适合与文件的读写使用;

2.async定义异步

3.await 执行异步

4.asyncio调用async函数,在web开发中不用考虑,在窗口联系中需要使用这个;

5.gevent异步使用

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值