1. 程式人生 > >python基礎-Process建立程序、join方法、實現ftp多程序

python基礎-Process建立程序、join方法、實現ftp多程序

程序概念

程序即正在執行的一個過程或者說一個任務。程序是對正在執行程式的一個抽象,而負責執行任務則是cpu
程式僅僅只是一堆程式碼而已,而程序指的是程式的執行過程。
程序的概念起源於作業系統,程序的建立,排程管理都歸作業系統管

一 作業系統的作用:
1:隱藏醜陋複雜的硬體介面,提供良好的抽象介面
2:管理、排程程序,並且將多個程序對硬體的競爭變得有序

二 多道技術:
1.產生背景:針對單核,實現併發
ps:
現在的主機一般是多核,那麼每個核都會利用多道技術
有4個cpu,運行於cpu1的某個程式遇到io阻塞,會等到io結束再重新排程,會被排程到4個
cpu中的任意一個,具體由作業系統排程演算法決定。

2.空間上的複用:如記憶體中同時有多道程式
3.時間上的複用:複用一個cpu的時間片
   強調:遇到io切,佔用cpu時間過長也切,核心在於切之前將程序的狀態儲存下來,這樣
        才能保證下次切換回來時,能基於上次切走的位置繼續執行

獲取程序id

getpid是獲得當前程序的程序號
getppid是獲得當前程序的父程序的程序號

import time,os
print(os.getpid(),os.getppid())
time.sleep(1000)

輸出如下:

1512 12032

這裡寫圖片描述

並行、併發概念

一 併發:單個cpu+多道技術就可以實現併發,(並行也屬於併發)
二 並行:同時執行,只有具備多個cpu才能實現並行
有四個核,六個任務,這樣同一時間有四個任務被執行,假設分別被分配給了cpu1,cpu2,cpu3,cpu4,一旦任務1遇到I/O就被迫中斷執行,此時任務5就拿到cpu1的時間片去執行,而一旦任務1的I/O結束了,作業系統會重新呼叫它(需知程序的排程、分配給哪個cpu執行,由作業系統說了算),可能被分配給四個cpu中的任意一個去執行

Process類的介紹

p.start() #只是在給作業系統發了一個訊號,讓作業系統去開程序(申請記憶體+拷貝父程序的地址空間)

方式一:


from multiprocessing import Process
import time

def task(name):
    print('%s is running' %name)
    time.sleep(2)

if __name__ == '__main__': #在windows系統下,開子程序的程式碼必須寫到這一行下面
    p=Process(target=task,args=('safly1',))
    p.start() #只是在給作業系統發了一個訊號,讓作業系統去開程序(申請記憶體+拷貝父程序的地址空間)
p1 = Process(target=task, kwargs={"name":"safly2"}) p1.start() print('主')

輸出如下:

主
safly1 is running
safly2 is running

方式二:


from multiprocessing import Process
import time

class Myprocess(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        time.sleep(3)
        print('%s is running' % self.name)


if __name__ == '__main__':  # 在windows系統下,開子程序的程式碼必須寫到這一行下面
    p = Myprocess('safly')
    p.start()  # p.run()
    print('主')

輸出如下:

主
safly is running

Process類的其他方法

from multiprocessing import Process
import time, random
def task():
    print('孫子運行了')
    time.sleep(3)

def piao(name):
    print('%s is piaoing' % name)
    time.sleep(random.randint(1, 3))
    print('%s is done' % name)
    p=Process(target=task,)
    p.start()

if __name__ == '__main__':
    p1=Process(target=piao,args=('alex',),name='xxxxxxxx')
    p1.start()
    print(p1.name)
    print(p1.pid)


    print(p1.is_alive())
    print('主')

輸出如下:

E:\python\python_sdk\python.exe E:/python/py_pro/3_Process物件的屬性與方法.py
xxxxxxxx
11816
True
主
alex is piaoing
alex is done
孫子運行了

Process finished with exit code 0

join方法

join:主程序等,等待子程序結束

from multiprocessing import Process
import time,random

def piao(name):
    print('%s is piaoing' %name)
    time.sleep(random.randint(1,3))
    print('%s is done' %name)

if __name__ == '__main__':
    p1=Process(target=piao,args=('alex',))
    p2=Process(target=piao,args=('wxx',))
    p3=Process(target=piao,args=('yxx',))

    p1.start()
    p2.start()
    p3.start()

    p3.join()  # join(p)
    p1.join() #join(p)
    p2.join() #join(p)

    print('主')

輸出如下:

alex is piaoing
wxx is piaoing
yxx is piaoing
alex is done
wxx is done
yxx is done
主

程序只要start就會在開始運行了,所以p1-p3.start()時,系統中已經有3個併發的程序了
而我們p1.join()是在等p1結束,沒錯p1只要不結束主執行緒就會一直卡在原地,這也是問題的關鍵
join是讓主執行緒等,而p1-p3仍然是併發執行的,p1.join的時候,其餘p2,p3仍然在執行,等#p1.join結束,可能p2,p3早已經結束了,這樣p2.join,p3.join直接通過檢測,無需等待
所以3個join花費的總時間仍然是耗費時間最長的那個程序執行的時間
上述例子可以簡寫成如下:

from multiprocessing import Process
import time,random

def piao(name):
    print('%s is piaoing' %name)
    time.sleep(random.randint(1,3))
    print('%s is done' %name)

if __name__ == '__main__':


    p1=Process(target=piao,args=('alex',))
    p2=Process(target=piao,args=('wxx',))
    p3=Process(target=piao,args=('yxx',))
    p_l=[p1,p2,p3]
    for p in p_l:
        p.start()


    for p in p_l:
        p.join()

    print('主')

利用多程序實現ftp套接字

我們之前寫過非多程序的tcp套接字通訊,這裡在貼出程式碼來看下
server

import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",8081))
server.listen(5)
while True:
    conn,addr = server.accept()
    while True:
        data = conn.recv(1024)
        if not data:break

        dataStr = data.decode("utf-8")
        print(dataStr)

        conn.send(dataStr.upper().encode("utf-8"))

    conn.close()

server.close()

client

import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",8081))

while True:
    msg = input("請輸入:")
    if not msg:continue

    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print(data.decode("utf-8"))
client.close()

我們要為server端新增多程序(client不做修改)

import socket
from multiprocessing import Process


def task(conn,addr):
    while True:
        try:
            msg = conn.recv(1024)
            if not msg:break
            conn.send(msg.upper())
        except ConnectionResetError:
            break


if __name__ == "__main__":
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(("127.0.0.1", 6087))
    server.listen(5)
    while True:
        conn, addr = server.accept()
        p = Process(target=task,args=(conn,addr))
        p.start()

這裡寫圖片描述