溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

操作系統(tǒng)簡(jiǎn)介&多進(jìn)程

發(fā)布時(shí)間:2020-04-04 04:14:09 來(lái)源:網(wǎng)絡(luò) 閱讀:621 作者:DevOperater 欄目:編程語(yǔ)言

1.操作系統(tǒng)

操作系統(tǒng)為程序員操作硬件提供了接口。程序員不需要直接寫(xiě)程序操作硬件,只需要按照一定的規(guī)范,把數(shù)據(jù)提交給操作系統(tǒng),操作系統(tǒng)回去操作硬盤(pán),CPU和內(nèi)存

1.1第一代計(jì)算機(jī)

"特點(diǎn)"
    沒(méi)有操作系統(tǒng)的概念,所有程序都是直接操控硬件
"工作過(guò)程"
   程序員預(yù)約一段時(shí)間,在這段時(shí)間一個(gè)程序員獨(dú)享計(jì)算機(jī),其他人等待
"優(yōu)點(diǎn)"
    程序員在申請(qǐng)的時(shí)間內(nèi)獨(dú)享資源,可以及時(shí)調(diào)整自己的程序
"缺點(diǎn)"
    浪費(fèi)資源,一段時(shí)間內(nèi)只有一個(gè)人使用

1.2第二代計(jì)算機(jī):批處理系統(tǒng)

"工作過(guò)程"
    多個(gè)程序員的代碼放在一起進(jìn)行提交,然后機(jī)器順序計(jì)算,得到多個(gè)程序員代碼的輸出
"優(yōu)點(diǎn)"
    批處理代碼,不再是一個(gè)程序員獨(dú)享計(jì)算機(jī),節(jié)省了時(shí)間
"缺點(diǎn)"
    1.整個(gè)流程需要人的參與,把多個(gè)程序員的代碼在機(jī)器之間搬動(dòng),進(jìn)行執(zhí)行和得到輸出
    2.計(jì)算機(jī)仍然是順序執(zhí)行的
    3.程序員不能獨(dú)享計(jì)算機(jī),不能即使調(diào)試得到結(jié)果,需要等到大家都提交完成,一起處理后得到結(jié)果,有問(wèn)題不能立刻處理

操作系統(tǒng)簡(jiǎn)介&多進(jìn)程

1.3第三代計(jì)算機(jī):多道程序設(shè)計(jì)

"解決第二代計(jì)算機(jī)中需要人參與的問(wèn)題"
    使用SPOOLING技術(shù),就不需要人在中間搬動(dòng)磁帶了
"解決第二代計(jì)算機(jī)順序執(zhí)行的問(wèn)題"
多道技術(shù)
    多道技術(shù)中的多道指的是多個(gè)程序,多道技術(shù)的實(shí)現(xiàn)是為了解決多個(gè)程序競(jìng)爭(zhēng)或共享一個(gè)CPU的有序調(diào)度問(wèn)題,解決方式是多路復(fù)用,分為時(shí)間上的復(fù)用和空間上的復(fù)用
    "空間上的復(fù)用:"將內(nèi)存分為幾部分,每部分放入一個(gè)程序,這樣,同一時(shí)間內(nèi)存中就有了多個(gè)程序
    "空間上復(fù)用的問(wèn)題:"程序之間的內(nèi)存必須是分割開(kāi)的,這種分割需要在硬件層面操作,由操作系統(tǒng)控制。如果內(nèi)存彼此不分割,則一個(gè)程序可以訪問(wèn)另外一個(gè)程序的內(nèi)存。
    首先喪失的是安全性,如qq程序可以訪問(wèn)操作系統(tǒng)的內(nèi)存,這就拿到了操作系統(tǒng)的權(quán)限。
    其次喪失的是穩(wěn)定性,如果qq程序退出,可能會(huì)導(dǎo)致操作系統(tǒng)的程序退出。
    "時(shí)間上的復(fù)用:"當(dāng)一個(gè)程序在等待I/O時(shí),或一個(gè)程序運(yùn)行了一段時(shí)間,CPU就切換,運(yùn)行其他程序。
"解決單個(gè)程序員不能獨(dú)享計(jì)算機(jī)的問(wèn)題"
    "分時(shí)操作系統(tǒng):"多個(gè)終端+多道技術(shù),可以多個(gè)程序員連接計(jì)算機(jī),操作系統(tǒng)采用多道的技術(shù),處理多個(gè)程序員的任務(wù)。所有的用戶(hù)以為自己獨(dú)享了計(jì)算機(jī)資源。
    第三代計(jì)算機(jī)廣泛采用了必須的保護(hù)硬件(程序之間的內(nèi)存彼此隔離后),分時(shí)系統(tǒng)才開(kāi)始流行。

1.4第四代計(jì)算機(jī):個(gè)人計(jì)算機(jī)

1.5總結(jié)

一:操作系統(tǒng)的作用
    1.隱藏復(fù)雜的硬件接口,提供良好的抽象接口。
    2.管理、調(diào)度進(jìn)程,并且將多個(gè)進(jìn)程多硬件的競(jìng)爭(zhēng)變得有序。
二:多道技術(shù)
    1.產(chǎn)生背景:針對(duì)單核,實(shí)現(xiàn)并發(fā)
      現(xiàn)在的主機(jī)一般是多核,多核都會(huì)使用多道技術(shù)
      有4個(gè)CPU,運(yùn)行在cpu1上的某個(gè)程序遇到io阻塞,會(huì)等到io結(jié)束再重新調(diào)度,對(duì)被調(diào)度到4個(gè)cpu中的任意一個(gè),具體由操作系統(tǒng)的調(diào)度算法決定。
    2.空間上的復(fù)用:內(nèi)存中同時(shí)存在多個(gè)程序,需要硬件支持,將多個(gè)程序的內(nèi)存空間分隔開(kāi)來(lái)。
    3.時(shí)間上的復(fù)用:復(fù)用一個(gè)cpu時(shí)間片。
       如果程序在進(jìn)行io處理,或一個(gè)程序占用cpu較長(zhǎng)時(shí)間,就會(huì)吧進(jìn)程的狀態(tài)保存下來(lái),去處理別的程序。下次CPU切換回來(lái),繼續(xù)上次的位置,繼續(xù)運(yùn)行。

2.進(jìn)程理論

2.1什么是進(jìn)程

進(jìn)程是正在運(yùn)行的代碼程序。負(fù)責(zé)運(yùn)行程序,執(zhí)行任務(wù)的是CPU。

2.2進(jìn)程與程序的區(qū)別

程序僅僅是一堆代碼
進(jìn)程是程序的運(yùn)行過(guò)程,運(yùn)行起來(lái)的代碼會(huì)在操作系統(tǒng)中產(chǎn)生一個(gè)進(jìn)程
同一個(gè)程序運(yùn)行兩次,是兩個(gè)進(jìn)程。

2.3并發(fā)與并行

無(wú)論是并發(fā)還是并行,在用戶(hù)看來(lái)都是'同時(shí)'運(yùn)行的
不管是進(jìn)程還是線程,都只是一個(gè)任務(wù)而已,真正做事的是CPU,但同一個(gè)CPU在同一時(shí)刻只能執(zhí)行一個(gè)任務(wù)
"并發(fā)":是偽并行,即看起來(lái)是同時(shí)運(yùn)行。單個(gè)cpu+多道技術(shù)可以實(shí)現(xiàn)并發(fā)
例如:你可能正在學(xué)習(xí),但突然有人找你聊天,你可能聊一會(huì),看一會(huì)視頻,等對(duì)方有回復(fù)了,你在回復(fù)。你就做到了做兩件事,看似同時(shí)進(jìn)行,但實(shí)際上你是一會(huì)學(xué)習(xí),一會(huì)回復(fù),在同一時(shí)間實(shí)際只做了一件事
"并行":同時(shí)運(yùn)行,需要具備多個(gè)CPU才能實(shí)現(xiàn)并行。
單核下,可以使用多道技術(shù),多核下,每個(gè)CPU也可以使用多道技術(shù)。
例如:有四個(gè)CPU,6個(gè)任務(wù),在同一時(shí)間有四個(gè)任務(wù)在執(zhí)行,分別分配給了cpu0,cpu1,cpu2,cpu3
如果cpu0上的任務(wù)遇到I/O,cpu0就會(huì)處理任務(wù)5,這就是單核下的多道技術(shù)
如果cpu0上的I/O結(jié)束了,那么操作系統(tǒng)會(huì)重新進(jìn)行分配,決定調(diào)度給那個(gè)CPU是操作系統(tǒng)算法和任務(wù)優(yōu)先級(jí)決定的。

2.4進(jìn)程的創(chuàng)建

"進(jìn)程創(chuàng)建的四種形式"
1.啟動(dòng)操作系統(tǒng),會(huì)創(chuàng)建一些進(jìn)程。linux中ps -aux查看進(jìn)程,windows中tasklist查看
2.一個(gè)進(jìn)程在運(yùn)行過(guò)程中開(kāi)啟子進(jìn)程。(os.fork,subprocess.Popen都可以開(kāi)啟子進(jìn)程)
3.windows上用戶(hù)雙擊某個(gè)軟件,Linux中啟動(dòng)某個(gè)服務(wù),都可以創(chuàng)建一個(gè)進(jìn)程。
4.批處理作業(yè)的初始化(只在大型機(jī)的批處理系統(tǒng)中應(yīng)用。)
"linux與Windows中的進(jìn)程的創(chuàng)建"
1.Windows中調(diào)用CreateProcess來(lái)創(chuàng)建進(jìn)程。
2.Unix中調(diào)用fork,fork會(huì)創(chuàng)建一個(gè)與父進(jìn)程一模一樣的副本
"兩者的相同與不同"
相同的是:進(jìn)程創(chuàng)建后,父進(jìn)程和子進(jìn)程有個(gè)字不同的地址空間(多道技術(shù)要求進(jìn)程之間內(nèi)存是相互隔離的),任何一個(gè)進(jìn)程中的數(shù)據(jù)要和其他進(jìn)程的數(shù)據(jù)相互隔離,互不影響。
不同的是:在Unix中,子進(jìn)程的初始地址空間是父進(jìn)程的一個(gè)副本,子進(jìn)程中的數(shù)據(jù)來(lái)源于父進(jìn)程,與父進(jìn)程中的數(shù)據(jù)是完全相同的,但windows中子進(jìn)程與父進(jìn)程并不是完全相同。

2.5進(jìn)程的終止

1.程序正常退出
2.報(bào)錯(cuò)退出
3.被kill掉

2.6進(jìn)程的層次結(jié)構(gòu)

無(wú)論UNIX還是Windows,進(jìn)程只有一個(gè)父進(jìn)程,不同的是
1.Unix中所有的進(jìn)程,都是以init進(jìn)程為根,組成樹(shù)形結(jié)構(gòu)。父子進(jìn)程共同組成一個(gè)進(jìn)程組,這樣,當(dāng)從鍵盤(pán)發(fā)出一個(gè)信號(hào),該信號(hào)會(huì)被發(fā)送給與鍵盤(pán)相關(guān)的進(jìn)程組中的所有成員。
2.在windows中,沒(méi)有進(jìn)程層次的概念,所有的進(jìn)程地位相同,唯一類(lèi)似于進(jìn)程層次的,是在創(chuàng)建進(jìn)程時(shí),父進(jìn)程會(huì)得到一個(gè)特別的令牌(稱(chēng)為句柄),該句柄可以用于控制子進(jìn)程,但是父進(jìn)程有權(quán)把該句柄傳給其他子進(jìn)程,這樣就沒(méi)有層次了。

2.7進(jìn)程的狀態(tài)

操作系統(tǒng)簡(jiǎn)介&多進(jìn)程

運(yùn)行中的進(jìn)程被調(diào)度到就緒態(tài)的原因
1.進(jìn)程自身遇到I/O阻塞,便要讓出CPU讓其他進(jìn)程去執(zhí)行,這樣就保證了CPU一直愛(ài)工作
2.與進(jìn)程無(wú)關(guān),操作系統(tǒng)原因,如果一個(gè)進(jìn)程占用時(shí)間過(guò)多,或者優(yōu)先級(jí)原因,而調(diào)用其他進(jìn)程去使用CPU

2.8進(jìn)程并發(fā)的實(shí)現(xiàn)

進(jìn)程并發(fā)的實(shí)現(xiàn)在于,硬件中斷一個(gè)正在運(yùn)行的進(jìn)程,會(huì)把該進(jìn)程的狀態(tài)信息進(jìn)行保存,為此,操作系統(tǒng)維護(hù)一個(gè)表格,即進(jìn)程表,每個(gè)進(jìn)程占用一個(gè)進(jìn)程表項(xiàng)
該表存放了進(jìn)程狀態(tài)的重要信息,這樣當(dāng)CPU再次調(diào)用時(shí),能從該進(jìn)程的上次終端位置繼續(xù)執(zhí)行,就好像沒(méi)有中斷過(guò)一樣。

操作系統(tǒng)簡(jiǎn)介&多進(jìn)程

3.開(kāi)啟進(jìn)程的兩種方式

3.1multiprocessing模塊介紹

python中的"多線程"是無(wú)法利用多核優(yōu)勢(shì)的
python中的"多進(jìn)程"是可以充分的利用多核CPU的資源,可以使用os.cpu_count()來(lái)查看cpu數(shù)
python中使用multiprocessing模塊來(lái)開(kāi)啟多個(gè)子進(jìn)程,使用threading來(lái)開(kāi)啟多個(gè)線程。
multiprocessing模塊功能眾多:支持子進(jìn)程、通信和共享數(shù)據(jù)、執(zhí)行不同形式的同步,提供了Process,Queue,Pipe,Lock等組件。
"進(jìn)程與線程不同,進(jìn)程沒(méi)有任何共享狀態(tài),進(jìn)程修改的數(shù)據(jù),改動(dòng)的僅限于該進(jìn)程內(nèi)。"

3.2process類(lèi)的介紹

Process([group [, target [, name [, args [, kwargs]]]]])
由該類(lèi)實(shí)例化得到的對(duì)象,可用來(lái)開(kāi)啟一個(gè)子進(jìn)程
"注意"
1.需要使用關(guān)鍵字的方式來(lái)制定參數(shù)
2.args指定的是傳給target函數(shù)的位置參數(shù),是一個(gè)元組形式,設(shè)置方式args=("a",2)
3.kwargs指定的是傳給target函數(shù)的位置參數(shù),是一個(gè)字典的形式,設(shè)置方式kwargs={a:2,b:"test"}
"參數(shù)介紹"
group:未使用,為None
target:表示調(diào)用對(duì)象,即子進(jìn)程要執(zhí)行的任務(wù),指向一個(gè)函數(shù)
args:表示target函數(shù)的位置參數(shù),元組形式,args=(1,2,'vita',)
kwargs:表示target函數(shù)的位置參數(shù),字典形式,kwargs={'name':'vita','age':18}
name:表示子進(jìn)程的名稱(chēng)
"方法介紹"
p.start():?jiǎn)?dòng)進(jìn)程,并調(diào)用該子進(jìn)程中的run()方法
p.run():進(jìn)程啟動(dòng)時(shí)運(yùn)行的方法,正是該方法去調(diào)用target指定的函數(shù),自定義的繼承自Process的類(lèi),需要實(shí)現(xiàn)該方法
p.terminate():強(qiáng)制終止進(jìn)程p,不會(huì)做任何的清理工作,
    如果p創(chuàng)建了子進(jìn)程,該子進(jìn)程就成了僵尸進(jìn)程
    如果p還保存了一個(gè)鎖,那么鎖也不會(huì)被釋放,進(jìn)而導(dǎo)致死鎖
p.is_alive():如果p在運(yùn)行,就返回True
p.join([timeout]):主線程等待p終止
    "注意"是主線程處于等待狀態(tài),而p處于運(yùn)行狀態(tài)
"屬性介紹"
p.daemon:默認(rèn)為False,
如果設(shè)為T(mén)rue,代表p為后臺(tái)運(yùn)行的守護(hù)進(jìn)程,當(dāng)p的父進(jìn)程終止時(shí),p也隨之終止
設(shè)置為T(mén)rue后,p不能創(chuàng)建自己的新進(jìn)程,必須在p.start之后設(shè)置
p.name:進(jìn)程的名稱(chēng)
p.pid:進(jìn)程的pid

3.3Process創(chuàng)建子進(jìn)程

注意:在windows中Process()必須放到# if __name__ == '__main__':下
"方式一"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process
def target_func(name):
   print("子進(jìn)程:",name)
if __name__ == '__main__':
# 實(shí)例化兩個(gè)對(duì)象,開(kāi)啟兩個(gè)子進(jìn)程
    p1=Process(name="p1",target=target_func,args=("p1",))# 這里一定要加',',否則TypeError: target_func() takes 1 positional argument but 2 were given
    p2=Process(name="p2",target=target_func,args=("p2",))
    p1.start()
    p2.start()
    print("主進(jìn)程") #會(huì)發(fā)現(xiàn)創(chuàng)建了子進(jìn)程,主進(jìn)程依舊在繼續(xù)運(yùn)行,所以先輸出了主進(jìn)程的內(nèi)容,然后運(yùn)行子進(jìn)程,

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
主進(jìn)程
子進(jìn)程: p1
子進(jìn)程: p2

Process finished with exit code 0
"方式二"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process
# 這里要繼承Process
class Func(Process):
   # 重用父類(lèi)中的init方法,并加入新參數(shù)
   def __init__(self,name):
      super().__init__()
      self.nm=name

   # 一定要寫(xiě)run 方法,start方法會(huì)自動(dòng)調(diào)用run方法
   def run(self): #
      print("子進(jìn)程",self.nm)
if __name__ == '__main__':
# 實(shí)例化兩個(gè)對(duì)象,開(kāi)啟兩個(gè)子進(jìn)程
    func = Func("p1")
    func.start()
    func1 = Func("p2")
    func1.start()
    print("主進(jìn)程")

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
主進(jìn)程
子進(jìn)程 p1
子進(jìn)程 p2

Process finished with exit code 0

3.4pid和ppid

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process
import os
# 這里要繼承Process
class Func(Process):

   def __init__(self,name):
      super().__init__()
      self.nm=name

   def run(self): #
      # 子進(jìn)程的ppid就是main的pid
      print("子進(jìn)程:%s,pid:%s,ppid:%s"%(self.nm,os.getpid(),os.getppid()))
if __name__ == '__main__':
    func = Func("p1")
    func.start()
    func1 = Func("p2")
    func1.start()
    # 主進(jìn)程的ppid就是你運(yùn)行py文件的程序的進(jìn)程號(hào),
    # 如果使用pycharm運(yùn)行,就是pycharm的進(jìn)程號(hào)
    # 如果使用cmd終端運(yùn)行,就是終端的進(jìn)程號(hào)
    print("主進(jìn)程:,pid:%s,ppid:%s"%(os.getpid(),os.getppid()))

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
主進(jìn)程:,pid:6100,ppid:11200
子進(jìn)程:p1,pid:8252,ppid:6100
子進(jìn)程:p2,pid:10784,ppid:6100

Process finished with exit code 0

4.Process方法和屬性詳解

4.1join()

在主進(jìn)程運(yùn)行過(guò)程中,可以開(kāi)啟子進(jìn)程,主進(jìn)程與子進(jìn)程的任務(wù)分為
1.在主進(jìn)程的任務(wù)與子進(jìn)程的任務(wù)彼此獨(dú)立時(shí),主進(jìn)程先執(zhí)行完成,還要等待子進(jìn)程執(zhí)行完成后才統(tǒng)一回收資源
2.如果主進(jìn)程的任務(wù)需要在執(zhí)行到某個(gè)階段,需要等待子進(jìn)程執(zhí)行完成后繼續(xù)執(zhí)行,就可使用join()
"join"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process
import os
import time
# 這里要繼承Process
class Func(Process):

   def __init__(self,name):
       super().__init__()
       self.nm=name

   def run(self): #

       print("子進(jìn)程:%s is running"%(self.nm))
       time.sleep(3)
       print("子進(jìn)程:%s is finishing" % (self.nm))
if __name__ == '__main__':

   p_list=[]
   p1 = Func("p1")
   # 只是發(fā)送信號(hào)給操作系統(tǒng),治愈操作系統(tǒng)何時(shí)執(zhí)行,還要看系統(tǒng)內(nèi)部的調(diào)用
   p1.start()
   p_list.append(p1)
   p2 = Func("p2")
   p2.start()
   p_list.append(p2)
   # 方法哦一個(gè)列表中,for循環(huán)來(lái)執(zhí)行join
   for p in p_list:
       p.join()
   print("主進(jìn)程運(yùn)行完成")

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
子進(jìn)程:p1 is running
子進(jìn)程:p2 is running
子進(jìn)程:p1 is finishing
子進(jìn)程:p2 is finishing
主進(jìn)程運(yùn)行完成

Process finished with exit code 0
進(jìn)程執(zhí)行了start()后,信號(hào)就已經(jīng)發(fā)送給了操作系統(tǒng),操作系統(tǒng)會(huì)根據(jù)自己的調(diào)度規(guī)則,進(jìn)行運(yùn)行
join()是讓主進(jìn)程等待多個(gè)子進(jìn)程的運(yùn)行,此時(shí)所有的子進(jìn)程還是并發(fā)執(zhí)行的,
所有的子進(jìn)程的運(yùn)行時(shí)間是運(yùn)行時(shí)間最長(zhǎng)的子進(jìn)程的運(yùn)行時(shí)間。當(dāng)所有子進(jìn)程運(yùn)行完成后,繼續(xù)執(zhí)行主進(jìn)程的代碼

4.2其他屬性和方法

"p.terminate(),p.is_alive,p.name,p.pid"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process
import os
import time
# 這里要繼承Process
class Func(Process):

   def __init__(self,name):
       super().__init__()
       self.nm=name

   def run(self): #

       print("子進(jìn)程:%s is running"%(self.nm))
       time.sleep(3)
       print("子進(jìn)程:%s is finishing" % (self.nm))
if __name__ == '__main__':

   p1 = Func("p1")
   # 只是發(fā)送信號(hào)給操作系統(tǒng),至于操作系統(tǒng)何時(shí)執(zhí)行,還要看系統(tǒng)內(nèi)部的調(diào)用
   p1.start()
   # 執(zhí)行了terminate(),就沒(méi)有執(zhí)行子進(jìn)程的代碼了
   p1.terminate()
   # 執(zhí)行terminate()也是發(fā)送給操作系統(tǒng)一個(gè)進(jìn)程終止信號(hào),但不會(huì)立刻終止
   print(p1.is_alive())
   print("主進(jìn)程")
   print("子進(jìn)程名:%s,子進(jìn)程pid:%s" %(p1.name,p1.pid))
   time.sleep(2)
   # 休息2秒后,才終止
   print(p1.is_alive())

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
True
主進(jìn)程
子進(jìn)程名:Func-1,子進(jìn)程pid:14768
False

Process finished with exit code 0

5.練習(xí)

5.1思考開(kāi)啟進(jìn)程的方式一和方式二各開(kāi)啟了幾個(gè)進(jìn)程?

總共有主進(jìn)程+開(kāi)啟的子進(jìn)程

5.2進(jìn)程之間的內(nèi)存空間是共享的還是隔離的?下述代碼的執(zhí)行結(jié)果是什么?

"進(jìn)程間的數(shù)據(jù)是相互隔離的,所以主進(jìn)程仍然輸出100,子進(jìn)程是0"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from multiprocessing import Process

def work():
    global n
    n=0
    print('子進(jìn)程內(nèi): ',n)

if __name__ == '__main__':
    n = 100  # 在windows系統(tǒng)中應(yīng)該把全局變量定義在if __name__ == '__main__'之上就可以了
    p=Process(target=work)
    p.start()
    p.join()
    print('主進(jìn)程內(nèi): ',n)

D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
子進(jìn)程內(nèi):  0
主進(jìn)程內(nèi):  100

Process finished with exit code 0

5.3基于多進(jìn)程實(shí)現(xiàn)并發(fā)的套接字通信?

"server"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from socket import *
from multiprocessing import Process

def talk(conn):
    while True:
        try:
            data = conn.recv(1024)
            if not data: break
            conn.send(data.upper())
        except ConnectionResetError:
            break

    conn.close()

def server(ip,port):
    server = socket(AF_INET, SOCK_STREAM)
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    server.bind((ip,port))
    server.listen(5)

    while True:
        conn, addr = server.accept()
        p = Process(target=talk, args=(conn,))
        p.start()

    server.close()

if __name__ == '__main__':
    server('127.0.0.1', 8080)
"client"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if not msg:continue

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

5.4思考每來(lái)一個(gè)客戶(hù)端,服務(wù)端就開(kāi)啟一個(gè)新的進(jìn)程來(lái)服務(wù)它,這種實(shí)現(xiàn)方式有無(wú)問(wèn)題?

如果客戶(hù)端過(guò)多,服務(wù)端就會(huì)開(kāi)啟很多個(gè)子進(jìn)程,會(huì)耗盡資源

5.5改寫(xiě)下列程序,分別別實(shí)現(xiàn)下述打印效果

1、改寫(xiě)下列程序,分別別實(shí)現(xiàn)下述打印效果

from multiprocessing import Process
import time
import random

def task(n):
    time.sleep(random.randint(1,3))
    print('-------->%s' %n)

if __name__ == '__main__':
    p1=Process(target=task,args=(1,))
    p2=Process(target=task,args=(2,))
    p3=Process(target=task,args=(3,))

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

    print('-------->4')
效果一:保證最先輸出-------->4
"上面的代碼不做更改,就是首先輸出4"
-------->4
-------->1
-------->3
-------->2
效果二:保證最后輸出-------->4
"p1.join()
p2.join()
p3.join()
這樣就能讓主進(jìn)程等待子進(jìn)程執(zhí)行完成后,繼續(xù)執(zhí)行主進(jìn)程,就可最后輸出4"
-------->2
-------->3
-------->1
-------->4
效果三:保證按順序輸出
"   p1.start()
        p1.join()
    p2.start()
        p2.join()
    p3.start()
        p3.join()"
-------->1
-------->2
-------->3
-------->4
2、判斷上述三種效果,哪種屬于并發(fā),哪種屬于串行?
"前兩種是并發(fā)執(zhí)行,最后一個(gè)是串行"
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI