首页 > 编程语言 > 详细

初识进程 线程 协程(一):进程

时间:2020-02-05 17:04:43      阅读:61      评论:0      收藏:0      [点我收藏+]

创建进程

def func(n):
    ......
if __name__ == __main__:
    p = Process(target=func, args = (1,))
    p.start()

多进程

m = 1
def task1(t):
    global m    # 由于m是不可变对象,所以设置全局变量
    while True:
        sleep(t)
        m += 1
        print(这是任务一。。。。。, os.getpid(), ---, os.getppid(), m=, m)     # getpid得到当前进程pid,getppid得到父(主)进程的pid

def task2(t):
    global m
    while True:
        sleep(t)
        m += 1
        print(这是任务二。。。。。, os.getpid(), ---, os.getppid(), m=, m)     # 子进程的ppid和父(主)进程的pid一致


n = 1
if __name__ == __main__:
    p1 = Process(target=task1, name=任务1, args=(0.1,))  # 创建子进程
    p2 = Process(target=task2, name=任务2, args=(0.2,))

    p1.start()  # 开启一个进程,并执行run方法        ps:run():执行进程
    p2.start()

    print(os.getpid())  # 主进程的pid
    print(p1.name)
    print(p2.name)  # 主进程,先运行主进程,无论主进程在那个位置
    for i in range(5):
        n += 1
        m += 1
        sleep(0.2)
        print(主进程n={},m={}.format(n, m))
    else:
        p1.terminate()
        p2.terminate()

    print(-end-)

‘‘‘
运行结果:
1376
任务1
任务2
这是任务一。。。。。 14636 --- 1376 m= 2
主进程n=2,m=2
这是任务一。。。。。 14636 --- 1376 m= 3
这是任务二。。。。。 7912 --- 1376 m= 2
这是任务一。。。。。 14636 --- 1376 m= 4
主进程n=3,m=3
这是任务二。。。。。 7912 --- 1376 m= 3
这是任务一。。。。。 14636 --- 1376 m= 5
这是任务一。。。。。 14636 --- 1376 m= 6
主进程n=4,m=4
这是任务二。。。。。 7912 --- 1376 m= 4
这是任务一。。。。。 14636 --- 1376 m= 7
这是任务一。。。。。 14636 --- 1376 m= 8
主进程n=5,m=5
这是任务二。。。。。 7912 --- 1376 m= 5
这是任务一。。。。。 14636 --- 1376 m= 9
这是任务一。。。。。 14636 --- 1376 m= 10
主进程n=6,m=6
-end-
‘‘‘

 

由此可见,父进程是先运行的(与位置无关),两个子进程是同时运行的。在这里,每个进程的进程id是始终不变的

对于全局变量m,每个进程访问时,都会有一个独立的m出现。各个进程可以独立运行,互不影响。所以进程之间不能用这种方式(全局变量)通信

大概就是下图这样:

技术分享图片

自定义进程:

class MyProcess(Process):
    def __init__(self, n):
        super(MyProcess, self).__init__()
        self.n = n
    def run(self):
        ......
if __name__ == __main__:
    p = MyProcess(args = (1,))
    p.start()

主要是重新定义run方法

 

进程池Pool:

def task(n):
  ......
def back(n):
  ......
if __name__ == __main__:
  p = Pool(5)
   lis = [...]
  for i in lis:
    # p.apply(target=task, args=(i,))    # 阻塞式
    p.apply_async(target=task, args=(i,), callback=back)    # 非阻塞式,callbacka将target的返回结果传给back
    pool.close()    # 添加任务结束
    pool.join()     # 插在主进程前,执行完才可以执行主进程

非阻塞式:全部添加到队列中,立刻返回,没有等待其他进程完成之后才结束(最大化利用cpu)

阻塞式:添加一个执行一个,若一个任务不结束,另一个任务就进不到cpu

 

进程间的通信:

利用队列(Queue)

 

def a(q):
    ......
    q.put(...)
    ......
def b(q):
    while not q.empty():
        .......
        q.get()
        ......        
if __name__ == __main__:
    q = Queue(5)
    p1 = Process(target=a, args=(q,))
    p2 = Process(target=b, args=(q,))
    try:
        p1.start()
        p1.join()  # 进程会同时开始,这样p2就会用空队列开始执行,
        p2.start()
    except:
        print(发成错误)

 

ps:1.队列没有put进值的时候,使用get方法会出现阻塞  2.超出队列长度,会出现阻塞

q = Queue(2)
# print(q.get())  # 在put之前使用get,会发生阻塞
q.put(1)
q.put(2)
# q.put(2)  # 超出队列长度会发生阻塞
print(q.get())

 

 

关于if __name__ == ‘__main__‘:

用来识别当前要执行的代码、方法的所属。执行本文件的方法、代码;避免其他文件引入(import)的方法、代码被执行

 

初识进程 线程 协程(一):进程

原文:https://www.cnblogs.com/xiaoqichaoren/p/12263567.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!