Java教程

进程的并行并发,同步异步阻塞非阻塞

本文主要是介绍进程的并行并发,同步异步阻塞非阻塞,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

进程的概念

# 进程是系统(操作系统)进行资源分配和调度的基本单位

程序:做事的过程,而且是没有生命周期的 # 做菜的菜谱
进程:是动态的,是有生命周期的   # 做菜的过程
协程:解决单线程下的高并发

# 进程中还可以开线程

线程就是干活的人,进程不是干活的人   #线程——>做饭的人
线程就是最小的执行单元

进程和线程都是有操作系统来调度的

进程的并行和并发(单核情况下)

# 并行:就是在一个精确的时间片刻,同一时刻同时发生
# 并发:在同一个时间段上,看似是同时执行的

1. i/o消耗(i/o密集型)   # 时间消耗
	  input:输入
    output:输出
    不需要用到CPU的
2. 计算密集型
	 需要占用CPU

同步异步阻塞非阻塞

1.同步与异步: 同步和异步关注的是消息通信机制
2. 阻塞与非阻塞:阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

1.同步与异步举例

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”
我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异
步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。
然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

2. 阻塞与非阻塞举例

阻塞和非阻塞:关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调
用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻
得到结果之前,该调用不会阻塞当前线程。还是上面的例子,你打电话问书店老板有没有《分布式系统》
这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式
调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有
返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

如何开启进程

from multiprocessing import Process

def write():
    with open('aaa', 'w') as f:
        f.write('hello')
write()    # 主进程

**# 一个进程中必须至少有一个线程**

**# 在wins中,开启进程必须写在__main__里面**
if __name__ == '__main__':
    p = Process(target=write)   #子进程

    **# 开启进程必须调用start方法**
    p.start()

    p1 = Process(target=write)

    p1.start()

Process类的参数

from multiprocessing import Process

def task(age, name):
    # with open('aaa', 'w') as f:
    #     f.write('hello')
    print(name)
    print(age)

# 在wins中,开启进程必须写在__main__里面
if __name__ == '__main__':

# target=None, name=None, args=(), kwargs={}, *, daemon=None     
# args以位置传参数   kwargs以关键字传参
    # p = Process(target=task, args=('egon', 18))
    p = Process(target=task, kwargs={'name': 'qq', 'age': 11})

    # 开启进程必须调用start方法
    p.start()

    print(p.name)  # 进程名:Process-1
**强调:**

需要使用关键字的方式来指定参数
args指定的为传给target函数的位置参数,是一个元组形式,**必须有逗号**

参数介绍:

group参数未使用,值始终为None
target表示调用对象,即子进程要执行的任务
args表示调用对象的位置参数元组,args=(1,2,'egon',)
kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
name为子进程的名称

Process类的方法

if __name__ == '__main__':
    p = Process(target=task, kwargs={'name': 'qq', 'age': 11})  #
    # **开启进程必须调用start方法**
    p.start() # 开启进程   通知操作系统去开启进程
    # p.terminate()  杀掉进程(不会立马杀死需要时间)
    # p.is_alive()   查看进程是否存活,如果p仍然运行,返回True
    # p.join()		 等待子进程执行完毕

类方法举例

from multiprocessing import Process
import time
def write():
    with open('aaa', 'a') as f:
        f.write('hello')

def task(age,name):
    print(name)
    print(age)

if __name__ == '__main__':
    p=Process(target=task,kwargs={'name':'qq','age':18})
    p.start()
    print(p.is_alive())
    p.terminate()
    time.sleep(2)     #如果没有这行代码terminate立即执行p.is_alive() ,结果为True,True
    print(p.is_alive())

运行结果:
True
False

类方法join举例

from multiprocessing import Process

def task(age,name):
    print(name)
    print(age)

if __name__ == '__main__':
    p=Process(target=task,kwargs={'name':'qq','age':18})
    p.start()
    p.join()  # 如果没有这行代码 ,结果为:先运行(end=======> )在运行(qq)和(18)
    print('end=======>')

运行结果:
qq
18
end=======>

Process类的属性介绍

if __name__ == '__main__':
    p = Process(target=task, kwargs={'name': 'qq', 'age': 11})  

    # 开启进程必须调用start方法
    # 守护进程:父进程执行完毕,子进程也立马结束
    # p.daemon = True # 必须在p.start()之前设置  # 主进程结束子进程立马结束

    # **强调**:p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程                     
    终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置

    p.start()  # 开启进程   通知操作系统去开启进程
    print(p.name)  # 进程名
    print(p.pid)   # 进程id
    p.daemon = True  # **强调**:一定要放在start之前, 守护进程

类的属性p.daemon举例

from multiprocessing import Process

def task(age,name):
    print(name)
    print(age)

if __name__ == '__main__':
    p=Process(target=task,kwargs={'name':'qq','age':18})
    p.daemon=True
    p.start()
    print('end=======>')

from multiprocessing import Process
import time
def task(age,name):
    print(name)
    print(age)

if __name__ == '__main__':
    p=Process(target=task,kwargs={'name':'qq','age':18})
    p.start()
    print(p.name)
    print(p.pid)
    time.sleep(10)
    print('end=======>')

获取进程id号

from multiprocessing import Process

import time
import os

def task(age, name):
    print("子进程的id号: %s" % os.getpid())   # 子进程pid   # os.getpid()获取当前id号
    print("父进程的id号:%s" % os.getppid())   # 主进程pid
    time.sleep(10)

if __name__ == '__main__':
    p = Process(target=task, kwargs={'name': 'qq', 'age': 11})  # Process——>子进程
    p.start()
    print(p.pid)   # pid——>是子进程的pid
    print("main里的主进程的id号:%s" % os.getpid())  # 主进程pid
	    print("main里面的父进程的id号:%s" % os.getppid())      # pycharm的pid
    time.sleep(10)
    print("end=========>")

同时运行多个进程

from multiprocessing import Process

import time
import os

def task(i):
    time.sleep(3)
    print(i)

if __name__ == '__main__':
    ll = []
    # for i in range(10):     # 同时开10个进程,结果无序,太快了
    #     p = Process(target=task, args=(i, ))  #
    #     p.start()

    #     p.join() # 变成串行(一个一个执行,等上一个进程执行完执行下一个)执行保持有序

    # for i in range(10):
    #     p = Process(target=task, args=(i,))  #
    #     p.start()
    #     ll.append(p)
    #
    # for j in ll:
    #     j.join()
    p = Process(target=task, args=(1, ))

    p.start()
    p.name = 'aaaa'
    print(p.pid)
这篇关于进程的并行并发,同步异步阻塞非阻塞的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!