沙雕系列——進程、線程、併發、並行(一)

作爲小白的我,總是被多進程和多線程弄暈,當然,很多面試官也很喜歡問此類問題,針對這個問題,特意製作這個沙雕漫畫來幫助小白的理解,同時加深對進程和線程的印象。
在這裏插入圖片描述
在這裏插入圖片描述

看完了以上的漫畫,想必大家對進程線程有了一定的瞭解,那麼接下來,我就舉一個生活中常見的例子,來幫助小白的理解。
1.單核cpu
在這裏插入圖片描述
假設只有一個線程,來看看要用多久。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xueli
# @Software: win10 Tensorflow1.13.1 python3.6.3
import time
import datetime


def func1(work):
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)

def func2(work):
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(3)

def func3(work):
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)

def func4(work):
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(1)

if __name__ == '__main__':
    start = time.time()
    func1(u'煮飯')
    func2(u'炒菜')
    func3(u'洗衣服')
    func4(u'拖地')
    print("總時:" ,time.time() - start)

運行結果:
在這裏插入圖片描述
PS:單核單線程是爲了幫助大家理解與記憶,現如今幾乎沒有單核CPU了吧。那麼問題來了,什麼是併發運行?什麼是並行運行呢?

一張圖解釋一下什麼是併發運行。
在這裏插入圖片描述
併發指的是應用能夠交替執行不同的任務,併發的關鍵是具有處理多個任務的能力,不一定要同時進行,併發有點類似於多線程的原理,多線程並非是同時執行多個任務,其實是計算機的操作系統通過時間片輪轉法等算法調度執行任務,是在以我們無法感覺到的速度,在切換不同的任務程序。讓我們誤以爲是"同時執行效果"。併發類似於兩個人交替使用一臺電腦工作,輪流執行。

一張圖解釋一下什麼是並行運行。
在這裏插入圖片描述
並行是指應用能夠同時執行不同的任務,並行的關鍵是具有同時處理多個任務的能力。並行類似於兩個人使用兩臺電腦,同時進行工作。
並行和併發的區別點就在於,一個是交替執行,一個是同時執行。最關鍵的點在於,是否是“同時”

接下來引入多線程:

import threading
import time
import datetime
import os

def func1(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func2(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(3)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func3(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func4(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(1)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))


if __name__ == '__main__':
    print('當前主進程: {}'.format(os.getpid()))
    start = time.time()
    threads = []
    t1 = threading.Thread(target=func1, args=(u'煮飯',))
    threads.append(t1)
    t2 = threading.Thread(target=func2, args=(u'炒菜',))
    threads.append(t2)
    t3 = threading.Thread(target=func3, args=(u'洗衣服',))
    threads.append(t3)
    t4 = threading.Thread(target=func4, args=(u'拖地',))
    threads.append(t4)
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print("共計用時{}秒".format((time.time()-start)))

運行結果:
在這裏插入圖片描述
這裏博主舉的多線程案例其實是並行運算啦。

2.多核CPU(以4核爲例)
在這裏插入圖片描述

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/4/24 14:15
# @Author  : xueli
# @File    : process.py
# @Software: win10 Tensorflow1.13.1 python3.6.3

import time
import datetime
import os
from multiprocessing import Process

def func1(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func2(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(3)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func3(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(4)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))

def func4(work):
    print('當前進程: {}'.format(os.getpid()))
    print('%s,我現在要——>%s' %(datetime.datetime.now(),work))
    time.sleep(1)
    print('%s,我已經完成了——>%s' % (datetime.datetime.now(), work))


if __name__ == '__main__':
    print('當前主進程: {}'.format(os.getpid()))
    start = time.time()
    process = []
    p1 = Process(target=func1, args=(u'煮飯',))
    process.append(p1)
    p2 = Process(target=func2, args=(u'炒菜',))
    process.append(p2)
    p3 = Process(target=func3, args=(u'洗衣服',))
    process.append(p3)
    p4 = Process(target=func4, args=(u'拖地',))
    process.append(p4)
    for p in process:
        p.start()
    for p in process:
        p.join()
    print("共計用時{}秒".format((time.time()-start)))

運行結果:
在這裏插入圖片描述
這裏創建了4個進程。由此可知,在這項工作中,單線程16秒,多線程4秒,多進程5.7秒。注意:進程與進程的切換要耗資源,所以平時工作中進程數不能開太大,進程數取決於CPU的核數。

持續更新~
如有問題,歡迎大佬給予批評指點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章