關於進程與線程的理解(python實現)

一、概念及區別

  * 概念
    1. 	進程:進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。每個進程都有自己的獨立內存空間,不同進程通過進程間通信來通信。由於進程比較重量,佔據獨立的內存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。
    2. 	線程:線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據
    3. 	協程:**協程是一種用戶態的輕量級線程,**協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
  * 區別
    1. 	進程和線程的區別[http://https://blog.csdn.net/qq_34974749/article/details/105442584](http://https://blog.csdn.net/qq_34974749/article/details/105442584)
    2. 	線程與協程的區別
  1. 一個線程可以擁有多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。

  2. 線程進程都是同步機制,而協程則是異步

3) 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態

多進程和多線程的同時運行,可以大大提高計算機的運行效率。許多任務既可以通過多進程實現,也可以通過多線程實現。利用多進程實現時,由於進程是申請和獲得系統資源的基本單位,進程之間界限明顯,單個進程的崩潰一般不會影響到其他進程的運行,因此,用多進程方法執行任務可靠性比較高,但是,由於每個進程擁有自己獨立的資源,使得多進程方法耗費系統資源較多。利用多線程實現時,由於同一進程的多個線程共享進程所擁有的資源,因此,用多線程方法執行任務資源耗費少,效率比較高,但是,由於多個線程共享相同的資源,單個線程的崩潰會影響到其他線程的運行,使得多線程方法的可靠性下降。實際應用中,到底是使用多進程、多線程還是多進程與多線程的結合,要視具體情況來確定。

#!/usr/bin/env python3 
#coding=utf-8 
""" 
@author:oxff
@github:https://github.com/oxff644
  """ 
#執行Linux命令和獲取主機CPU核數 
from _multiprocessing import cpu_count
import subprocess 
subprocess.call(['pwd']) 
subprocess.call(['ls','-l','/'])
num_cores =cpu_count() 
print('Your computer has %d cores.' % num_cores)

二、多進程編程與多線程編程
1.多進程編程

#!/usr/bin/env python3
#coding=utf-8
"""
@author:oxff
@github:https://github.com/oxff644
"""
#利用多進程爲客戶端提供文件下載服務
from multiprocessing import Process
import socket
import os
def sendfile(conn):
    strl =conn.recv(1024)
    filename =strl.decode('utf-8')
    print('I am child process,my ID is',os.getpid())
    print("The client requests my file:",filename)
    if os.path.exists(filename):
        print('I have %s,begin to download!' %filename)
        conn.send(b'yes')
        conn.recv(1024)
        size =1024
        with open(filename,'rb') as f:
            while True:
                data =f.read(size)
                conn.send(data)
                if len(data)<size:
                    break
                print('%s is download successfully!' %filename)
    else:
        print('sorry,I have no %s' % filename)
        conn.send(b'no')
    conn.close()
s= socket.socket(socket.AF_PACKET,socket.SOCK_STREAM)
s.bind('192.168.0.103','8088')
s.listen(100)
print('I am parent process,my ID is',os.getpid())
print('wait for connecting.....')
while True:
    (conn,addr)=s.accept()
    p =Process(target=sendfile,args =(conn,))
    p.start()
2.多線程編程
#!/usr/bin/env python3
#coding=utf-8
"""
@author:oxff
@github:https://github.com/oxff644
"""
#利用多線程爲客戶端提供文件下載服務
import threading
import socket
import os
def sendfile(conn):
    str1 =conn.recv(1024)
    filename =str1.decode('utf-8')
    print('I am',threading.current_thread().name)
    print('The client requests my file:',filename)
    if os.path.exists(filename):
        print('I have %s,begin to download!' %filename)
        conn.send(b'yes')
        conn.recv(1024)
        size =1024
        with open(filename,'rb') as f:
            while True:
                data =f.read(size)
                conn.send(data)
                if len(data)<size:
                    break
        print('%s is downloaded successfully' % filename)
    else:
        print('Sorry~~,I have no %s' % filename)
        conn.send(b'no')
    conn.close()
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('192.168.0.103',8088))
s.listen(100)
print('wait for connecting....')
while True:
    (conn,addr) =s.accept()
    t =threading.Thread(target=sendfile,args=(conn,))
    t.start()

對比進程池和線程池,進程池中不同子進程對應的函數可以不同,但線程池所有線程對應的函數都是同一個函數,這就導致了實參組織方式的不同,進程池每個子進程參數單獨指定,而線程池中每個線程的參數從列表中依次取得。

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