A. python同時打開幾個程序默認運行哪一個
操作系統的作用
隱藏醜陋復雜的硬體介面,提供良好的抽象介面
管理、調度進程,並且將多個進程對硬體的競爭變得有序
2. 多道技術產生背景
針對單核,實現並發
現在的主機一般是多核,那麼每個核都會利用多道技術
有 4 個 cpu,運行於 cpu1 的某個程序遇到 io 阻塞,會等到 io 結束再重新調度
會被調度到 4 個 cpu 中的任意一個,具體由操作系統調度演算法決定
3. 多道技術空間上的復用:如內存中同時有多道程序
4. 多道技術時間上的復用
復用一個 cpu 的時間片
注意,遇到 io 切,佔用 cpu 時間過長也切
核心在於切之前將進程的狀態保存下來
這樣才能保證下次切換回來時,能基於上次切走的位置繼續運行
進程的概念
進程是一個具有一定獨立功能的程序關於某個數據集合的一次運行活動
進程是操作系統動態執行的基本單元
在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元
進程與程序的區別
程序是指令和數據的有序集合,是一個靜態的概念。程序可以作為一種軟體資料長期存在,是永久的
進程是程序在處理機上的一次執行過程,它是一個動態的概念。進程是有一定生命期的,是暫時的
5. 注意:同一個程序執行兩次,就會在操作系統中出現兩個進程。所以可以同時運行一個軟體,分別做不同的事情也不會混亂,比如可以打開兩個Pycharm做不同的事
6. 進程調度
要想多個進程交替運行,操作系統必須對這些進程進行調度
這個調度也不是隨即進行的,而是需要遵循一定的法則
由此就有了進程的調度演算法:先來先服務調度演算法、短作業優先調度演算法、時間片輪轉法、多級反饋隊列
並行和並發
並行是指在一個時間點上,有多個進程在被 cpu 計算,比如賽跑,兩個人都在不停的往前跑
並發是指資源有限的情況下,在一個時間段上,有多個進程在被 cpu 計算,交替輪流使用資源
並行與並發的區別
並行是從微觀上,也就是在一個精確的時間片刻,有不同的程序在執行,這就要求必須有多個處理器
並發是從宏觀上,在一個時間段上可以看出是同時執行的,比如一個伺服器同時處理多個 session
進程的三狀態
在程序運行的過程中,由於被操作系統的調度演算法控制,程序會進入幾個狀態
就緒
運行
阻塞
2. 舉例說明什麼是 argv,什麼是阻塞
import sys
print(sys.argv)
# 運行結果:
['G:/course_select/進程的概念.py']
# argv 指參數
# sys.argv 是 Python 解釋器在運行的時候傳遞進來的參數
# 首先在cmd輸入以下信息:
python G:/course_select/進程的概念.py
# 列印結果:
['G:/course_select/進程的概念.py']
# 然後在cmd中切換路徑到G盤,接著輸入 python course_select/進程的概念.py
# 列印結果:
['course_select/進程的概念.py']
# 接著,再在cmd中輸入:python course_select/進程的概念.py 123 abc
# 列印結果:
['course_select/進程的概念.py', '123', 'abc']
# 因此,以下程序不能在編輯器里運行,只能在 cmd 裡面使用 Python 運行本文件
# 然後要在後面加上 aaa bbb
# 就像上面的 python course_select/進程的概念.py 123 abc 一樣
if sys.argv[1] == "aaa" and sys.argv[2] == "bbb":
print("登錄成功")
else:
print("登錄失敗")
exit()
print(666)
# 而如果使用input(),其實就是一種阻塞
3. 進程的三狀態圖
.png
同步非同步
同步:形象的說,一件事的執行必須依賴另一件事的結束,強調的是順序性
非同步: 形象的說,兩件事情可以同時進行
注意:同步非同步和並行、並發沒關系
阻塞:等待,比如 input sleep recv accept recvfrom
非阻塞:不等待,start/terminate 都是非阻塞的
阻塞與非阻塞主要是從程序(線程)等待消息通知時的狀態角度來說的
可以分為四類:
同步阻塞
非同步阻塞
同步非阻塞
非同步非阻塞
start/terminate 都是非阻塞的
進程模塊
跟進程相關的基本都在這個模塊里:multiprocessing
父進程與子進程的對比分析
父進程,比如運行本文件
子進程,運行 Process(target=func).start()
父進程與子進程數據隔離
主進程等待子進程結束之後再結束
子進程和主進程之間默認是非同步的
from multiprocessing import Process
import time
def func():
time.sleep(1)
print(666)
if __name__ == "__main__":
# 開啟了一個新的進程,在這個新的進程里執行的 func()
Process(target=func).start()
time.sleep(1)
# 主進程
print(777)
# 777
# 666
# 運行結果仔細觀察發現有非同步的效果
# 也就是說,主進程和新的進程同時執行
3. 上面的示例中為什麼要有 if __name__ == "__main__"?其實這是 windows 操作系統開啟子進程的方式問題
4. 繼續深入
import time
import os
from multiprocessing import Process
def func():
time.sleep(1)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
# 代碼執行到這里並不代表開啟了子進程
p = Process(target=func)
# 開啟了一個子進程,並執行func()
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 主進程運行的結果
777 12340 1636
# 子進程運行的結果
666 7604 12340
# 由上面兩行結果可以得出:
# 利用 os.getpid() 證明兩個進程不一樣
# 另外每次運行,os.getpid() 結果都不一樣
# 但是,12340 是主進程的 id,7604 是子進程的 id
# 1636 是 Pycharm 的 id,排列特點不變
5. 開啟多個相同的子進程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(3)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
for i in range(10):
p = Process(target=func)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 這里需要注意一點:Python 程序一直都是逐行執行
# 但是因為這里設置了時間延遲,因此會先執行主程序的代碼
# 運行結果:
777 29006 3833 # 暫停 2s 後再有下面的結果
666 29007 29006
666 29009 29006
666 29008 29006
666 29010 29006
666 29013 29006
666 29011 29006
666 29012 29006
666 29014 29006
666 29016 29006
666 29015 29006
# 觀察結果發現主進程只運行了一次
# 然後剩下的全是一個子進程重新運行的結果
# 主進程運行完不會結束,它會等子進程全部運行結束
# 注意變數 p 拿到的是最後一個子進程的 id
6. 開啟多個不同的子進程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(2)
print(666, os.getpid(), os.getppid())
def func2():
print(111)
if __name__ == "__main__":
for i in range(3):
p = Process(target=func)
p.start()
for i in range(2):
p = Process(target=func2)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 運行程序時仔細觀察結果顯示順序:
111
111
777 29316 3833
666 29319 29316
666 29317 29316
666 29318 29316
7. 給子進程傳參示例
from multiprocessing import Process
def func(name):
print(666, name)
if __name__ == "__main__":
p = Process(target=func,args=(777,)) # 注意是一個元組
p.start()
import time
from multiprocessing import Process
def func(num, name):
time.sleep(1)
print(num, "hello", name)
if __name__ == "__main__":
for i in range(10):
p = Process(target=func, args=(i, "abc"))
p.start()
print("主進程")
# 運行結果:
666 777
主進程
0 hello abc
2 hello abc
1 hello abc
3 hello abc
5 hello abc
4 hello abc
6 hello abc
7 hello abc
8 hello abc
9 hello abc
# 多運行幾次,發現子進程並不是完全按順序運行的
# 比如上面先出結果 2 hello abc,再出結果 1 hello abc
8. 子進程可以有返回值嗎:不能有返回值,因為子進程函數中的返回值無法傳遞給父進程
import time
from multiprocessing import Process
def func():
time.sleep(3)
print("這是子進程,3s後才運行")
if __name__ == "__main__":
Process(target=func).start()
print("主進程")
# 運行結果:
主進程
這是子進程,3s後才運行
# 主進程會默認等待子進程結束之後才結束
# 因為父進程要負責回收子進程佔用的操作系統資源
相關資源:Python多進程寫入同一文件的方法_python多進程寫入同意文件-其它...
文章知識點與官方知識檔案匹配
Python入門技能樹首頁概覽
194693 人正在系統學習中
點擊閱讀全文
打開CSDN,閱讀體驗更佳
Python多進程(一)進程及進程池_程序員-夏天的博客
print("主進程結束") 通過上述代碼我們發現,multiprocessing.Process幫我們創建一個子進程,並且成功運行,但是我們發現,在子進程還沒執行完的時候主進程就已經死了,那麼這個子進程在主進程結束後就是一個孤兒進程,那麼我們可以讓主進程等待...
Python多進程之Process、Pool、Lock、Queue、Event、Semaphore、Pipe_大 ...
1. Python創建進程類Process python的multiprocessing模塊提供了一個創建進程的類Precess,其創建有以下兩種方法: 創建Process類的實例,並指向目標函數和傳遞參數 自定義一個類並繼承Process類,重寫__init__()和run()方法 ...
python兩個進程同時開啟只運行了一個_二十二、 深入Python的進程和線程(上篇)...
「@Author: Runsen」進程(Process)和線程(Thread)都是操作系統中的基本概念,它們之間有一些優劣和差異,那麼在Python中如何使用進程和線程?CPU計算機的核心是CPU,它承擔了計算機的所有計算任務,CPU就像一個工廠,時刻在運行著,而操作系統管理著計算機,負責任務的調度、資源的分配和管理。進程進程是指在系統中能獨立運行並作為資源分配的基本單位,它是由一組機器指令、數據...
繼續訪問
python啟動多個進程_Python多處理:只有一個進程正在運行
由於注釋表明您希望使用初始化程序和initargs參數傳遞featureVector.在Unix類型的系統上,這將導致大量的性能提升(即使selLabel中只有1個項目),因為該值將使用os.fork基本上免費傳遞給子進程.否則,每次調用foo時,featureVector都將被父進程pickle,通過管道傳遞並由子進程進行unpickled.這將花費很長時間,並且基本上將序列化所有子進程,因為它...
繼續訪問
python多進程多線程,多個程序同時運行_陳逸飛_p的博客_pyth...
python 模塊應用 開發工具 pycharm 實現方法 多任務的實現可以用進程和線程來實現 進程—> 線程---> 多任務應用 多進程操作 比如下載多個文件, 利用cpu 資源 提高效率 多任務: 同一時間執行多個任務, 比如windows操作系統 執行...
python多進程單例_Python多線程處理實例詳解【單進程/多進程】
python — 多線程處理 1、一個進程執行完後,繼續下一個進程 root@72132server:~# cd /root/python/multiprocess/ root@72132server:~/python/multiprocess# ls multprocess.py root@72132server:~/python/multiprocess# cat multprocess...
系統編程__2__父子進程的創建和回收
系統編程 這里寫的是對於小白來說更多的了解系統編程的文章,有寫的不對的地方還懇請各位大佬指出錯誤,小編一定會多多採納[手動多謝]。 那麼,上一次我們稍微了解了一下關於系統編程的一些主要內容[沒有看到的童鞋還請去上一篇文章稍微復習一下噢]。 這節課,我們先來想一想,我們為什麼要學系統編程呢?原因很簡單,我們要充分的利用CPU的性能,CPU和我們人類不太一樣,我們人類大多數情況下,在同一時間,只能完成一件事,而CPU作為無數科學家的心血當然不會這么簡單,CPU能夠同時進行多個進程,這里的進程我們可以理解成任務,
繼續訪問
android 10 system/core無法列印log問題
1.關閉重定向 system/core/init/util.cpp --- a/init/util.cpp +++ b/init/util.cpp @@ -454,7 +454,7 @@ static void InitAborter(const char* abort_message) { // SetStdioToDevNull() must be called again in second stage init. void SetStdioToDevNull(char** argv) { ...
繼續訪問
Python多進程1 一個多進程實例_BBJG_001的博客
下執行,job('主進程step1###')p1=mp.Process(target=job,args=('新進程>>>',))# 創建一個進程# 注意當只有一個參數的時候,一定要在參數後面加一個逗號,因為args需要是一個可以迭代的參量p1.start()# 開始執行新進程# p...
熱門推薦 python多進程多線程,多個程序同時運行
python 多線程 多進程同時運行 多任務要求 python 基礎語法 python 文件目錄操作 python 模塊應用 開發工具 pycharm 實現方法 多任務的實現可以用進程和線程來實現 進程—> 線程----> 多任務應用 多進程操作 比如下載多個文件, 利用cpu 資源 提高效率 多任務: 同一時間執行多個任務, 比如windows操作系統 執行方式有兩種( 表現形式 ) 並發 在單核cpu中: 在一段時間內交替執行多個任務, 例如單核cpu 處理多任務, 操作系統讓各個任務交
繼續訪問
fork()函數
多進程通信 fork()函數
繼續訪問
(1/7)Electron教程(一)什麼是 Electron,由來、適用場景 和 Electron 的環境搭建(1/7)
最近自己有個小的需求,是做一個能編輯本地特定文本的工具,需要跨平台, Windows 和 macOS,這樣,如果用原生開發的話,Windows 就要用c#macOS 就要用swift,學習成本高,並且學完用處也不是很大。我本身是前端開發的,發現了這個electron能滿足我的需求,跨平台運行,內部是 js 驅動的,簡直就是如魚得水。順便把學習的經歷寫出來,分享需要的人,我會按標題序號漸進式地編寫內容。electron。...
繼續訪問
fork()詳解
<一>: fork()函數用來創建新的進程,它的特點是調用一次返回兩次( 在原來的進程中返回新進程的 PID(新進程的 PID 肯定不等於 0), 在新進程中返回為 0.) 函數原型:pid_t fork(void); pid_t getpid(); 獲取當前進程的 pid 值。 pid_t getppid(); 獲取當前進程的父進程 pid 值。 圖一 如圖一所...
繼續訪問
fork()函數詳解
目錄 1.基本了解: 2.fork函數的了解: 3.僵死進程: 1.基本了解: 一個進程,包括代碼、數據和分配給進程的資源。fork 函數會新生成一個進程,調用 fork 函數的進程為父進程,新生成的進程為子進程。在父進程中返回子進程的 pid,在子進程中返回 0,失敗返回-1。 為什麼兩個進程的fpid不同呢,這與fork函數的特性有關。fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值: 1)在父進程中,fork返回新創建子進程的進程...
繼續訪問
Electron在Windows下的環境搭建
Electron作為一種用javascript寫桌面程序的開發方式,現在已經被大眾接受。下面就介紹如何在windows(>win7)下快速搭建Electron開發環境。 1. nodejs 的安裝 從nodejs 下載最新版本的windows安裝程序進行安裝,我下載的是v6.9.1,安裝時一路默認即可,這個安裝會把nodejs和npm配置到系統PATH中,這樣在命令行的任何位置都可以直接...
繼續訪問
python多線程pool_Python mutiprocessing多線程池pool操作示例
本文實例講述了Python mutiprocessing多線程池pool操作。分享給大家供大家參考,具體如下:python — mutiprocessing 多線程 pool腳本代碼:root@72132server:~/python/multiprocess# lsmultiprocess_pool.py multprocess.pyroot@72132server:~/python/multi...
繼續訪問
最新發布 python入門開發學習筆記之守護進程
本節重點 了解守護進程的概念 本節時長需控制在5分鍾內 一 守護進程 主進程創建子進程,然後將該進程設置成守護自己的進程,守護進程就好比崇禎皇帝身邊的老太監,崇禎皇帝已死老太監就跟著殉葬了。 關於守護進程需要強調兩點: 其一:守護進程會在主進程代碼執行結束後就終止 其二:守護進程內無法再開啟子進程,否則拋出異常:AssertionError: daemonic processes are not allowed to have children 如果我們有兩個任務需要並發執行,那麼開一個主進程和一個子進程分
繼續訪問
用python進行多進程編程時,只有主進程可以運行,子進程貌似沒有運行是什麼原因?
找了半天,原來是這個原因!這是因為multiprocessing模塊在交互模式是不支持的,在 cmd 里頭輸入 python xxx.py 來運行起來,你就可以看到子進程的執行了。
繼續訪問
linux中fork() 函數詳解
fork入門知識 一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變數不同,兩個進程也可以做不同的事。 一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都復制到新的新進程中,只有少數值與原來的進程的值不同。相當於克隆了...
繼續訪問
Windows版 Node.js 安裝詳解以及Electron安裝
Windows Node.js 安裝詳解以及Electron安裝詳解,示例版本:node v10.15.0/npm6.4.1 介紹: 簡單的說 Node.js 就是運行在服務端的 JavaScript。 Node.js 是一個基於Chrome JavaScript 運行時建立的一個平台。 Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執...
繼續訪問
Electron 簡介
本教程我們來學習 Electron 的基礎知識,下面我們先來學習一下什麼是 Electron。 Electron是什麼 Electron 是是 GitHub 開發的一個開源框架。它允許使用 Node.js(作為後端)和 Chromium(作為前端)完成桌面 GUI 應用程序的開發。 Electron 可以用於構建具有 HTML、CSS、JavaScript 的跨平台桌面應用程序,它通過將 Chromium 和 node.js 合同一個運行的環境中來實現這一點,應用程序可以打包到 Mac、Windows 和
繼續訪問
Election的優缺點
優點 原生的介面(菜單、消息提醒、系統托盤等)。 上手難度低。能夠使用react、vue等前端框架,能方便地遷移前端組件,構建出漂亮的桌面應用。 方便熱更新 調試和測試方便 Electron使用node.js。因此,您可以導入Chrome應用程序中不容易使用的許多模塊 Electron文檔要好得多,盡管它是一個更年輕的平台 缺點 不適合開發輕量級的應用。即使一個electron的項目框架,也包含chromium內核,打包完接近200G。 相比c++開發的桌面應用,性能遠遠不如後者。 啟動速
繼續訪問
[electron]終極奧義 五千字教程丟給你
前言 本文包含打包、自動更新、簡易API、調試、進程通信等相關知識點,內容較多,可能會引起不適,請酌情查看(手動滑稽)。 electron 簡介 electron是由Github開發,是一個用Html、css、JavaScript來構建桌面應用程序的開源庫,可以打包為Mac、Windows、Linux系統下的應用。 electron是一個運行時環境,包含Node和Chromium,可以理解成把we...
繼續訪問
深入理解Java中的wait() 方法
使用場景 當某個線程獲取到鎖後,發現當前還不滿足執行的條件,就可以調用對象鎖的wait方法,進入等待狀態。 直到某個時刻,外在條件滿足了,就可以由其他線程通過調用notify()或者notifyAll()方法,來喚醒此線程。 這篇文章將側重於討論wait()方法對於線程狀態的影響,以及被喚醒後線程的狀態變更。 條件 只有已經獲取鎖的線程,才可以調用鎖的wait方法,否則會拋出異常IllegalMonitorStateException。 比如下面的代碼,A獲得了鎖後,主動調用wait方法釋放鎖和
繼續訪問
用Electron開發桌面應用的避坑指南(文末送書)
送一波高質量Web開發圖書,送5本書籍,隨你挑。抽獎規則見本文最後!抽獎規則見本文最後!抽獎規則見本文最後!如今,Electron 領域發生了重大的變革,Electron 版本更新換代極快...
繼續訪問
python多進程只有一個進程在執行
python兩個進程同時開啟只運行了一個。
B. 開機時電腦後台運行的程序太多,如何關閉不需要的程序
電腦開機自啟動程序過多,必將影響電腦的開機速度和運行速度。
關閉不需要的開機自啟動程序的解決辦法如下:
一、利用系統配置實用程序關閉開機自啟動程序。本方法適用於明確了解哪些程序不需要開機自運行。
1、點擊桌面開始-運行。
2、在彈出的運行窗口的「打開」欄輸入:msconfig,並回車。
3、在彈出的系統配置實用程序窗口,點擊進入「啟動」選項卡,找到不需要開機自啟動的程序,去掉前面的勾選,在點擊應用和確定。
4、重啟電腦,關閉的啟動程序將不再開機自動運行。
二、利用安全軟體如360安全衛士的優化加速功能關閉不需要的開機自啟動程序。本方法適用於不了解哪些程序是否需要開機自運行。
1、下載、安裝、運行360安全衛士。如果已經安裝,則點擊桌面右下角處的360安全衛士圖標,打開其主界面。
2、點擊運行主界面當中的「優化加速」。
3、根據提示或推薦值自動選擇進行優化,以關閉不需要的開機自運行程序。.可能是鍵盤和滑鼠連接有問題或本身就有問題。
2.建議關機之後,重新插一下鍵盤,內注意,如果容是USB介面的鍵盤,不要插在藍色插口上,因為藍色插口是USB3.0,可能需要驅動支持。確保連接無誤後開機,看看自檢時鍵盤燈是否點亮,系統啟動完成後,你可以按一下CAPS LOCK鍵或NUM LOCK鍵,看看相應的指示燈是否正常,實在不行就需要換一塊鍵盤試試。
3.滑鼠和鍵盤一樣,USB滑鼠也要插在非藍色插口,看看滑鼠燈是否點亮,系統是否自動安裝硬體驅動,如果沒有任何反應,燈也不亮,可能滑鼠有問題或主板的介面有問題,需要更換滑鼠以確認。如果換鍵盤滑鼠都不能解決問題,就極有可能是主板介面有問題了
主機開機後,顯示屏,鍵盤滑鼠都沒反應有三種情況:
1、內存條松動、接觸不好、積塵,都會造成屏幕不顯示。
解決方法:拔掉電源,取下內存條,用橡皮除去介面處的浮塵,再用信紙擦拭乾凈。將內存條對位,雙手食指頂住卡座兩端,大拇指壓住內存條,向下壓,聽到「咔」緊聲,就OK。
2、主板問題。解決方法:拔掉電源,取下主板電池,將CMOS跳線,跳到"colse"位置,保持五分鍾以上,安上電池,恢復跳線。就OK。或用回形針讓主板上的CMOS正負極導通五分鍾以上,也會OK.。
3、電源有問題。 解決方法:拔掉主板電源介面接頭,用回形針連通「綠」和「黑」線,如果電源風扇不轉動,證明有問題,需更換。
蘋果電腦滑鼠沒反應怎麼辦
分析原因:
1.有線滑鼠損壞
2.USB口損壞,間接意味著主板損壞
3.沒有安裝驅動或驅動崩潰
解決方案:
1.更換滑鼠,有線或無線均可,最好蘋果牌的
2.拿到蘋果售後送修,國行港行機在保非人為損壞下可以換新,其餘的支付費用
3.去蘋果官網下載驅動安裝,注意選擇正確的機型對應的BootCamp驅動
蘋果電腦滑鼠沒反應
蘋果電腦滑鼠沒反應
你們知道滑鼠連接電腦後沒反應是什麼原因嗎,下面是學習啦小編帶來的關於蘋果電腦滑鼠沒反應是怎麼回事的內容,歡迎閱讀!
蘋果電腦滑鼠沒反應的原因一:
1.重新啟動電腦,讓它從新搜索你的藍牙滑鼠
2.確定你在windows下沒有使用你的滑鼠,如果使用了,從新啟動電腦
3.檢查你的驅動
4.以上還不行,如果在一年內,帶上你的購買憑證,到經銷商那裡讓他給你換新的!
蘋果電腦滑鼠沒反應的原因二:
1內存條松動接觸不好積塵,都會造成屏幕不顯示
解決方法:拔掉電源,取下內存條,用橡皮除去介面處的浮塵,再用信紙擦拭乾凈將內存條對位,雙手食指頂住卡座兩端,大拇指壓住內存條,向下壓,聽到咔緊聲,就OK
2主板問題解決方法:拔掉電源,取下主板電池,將CMOS跳線,跳到"colse"位置,保持五分鍾以上,安上電池,恢復跳線就OK或用回形針讓主板上的CMOS正負極導通五分鍾以上,也會OK.
3電源有問題 解決方法:拔掉主板電源介面接頭,用回形針連通綠和黑線,如果電源風扇不轉動,證明有問題,需更換
蘋果電腦滑鼠沒反應的原因三:
1)USB介面異常
包括USB介面供電問題,接觸不良,USB介面損壞等需逐一排查,更換其他USB介面確認原USB介面是否異常;
2)滑鼠驅動是否已安裝
確認蘋果的第三方滑鼠驅動是否有安裝,是否安裝成功,重新安裝確認後在確認故障是否還存在
3)BIOS中禁用了USB介面
BIOS禁用USB介面時,鍵鼠設備接在禁用介面上,開機和進BIOS是可以用的,但系統下無法使用,此時只需進BIOS,將對應的USB port設置為enable狀態,保存退出BIOS即可
4)設備管理器中禁用了相應的鍵鼠
接另一套鍵鼠開機進系統後,打開設備管理器,確認原鍵鼠是否是被禁用狀態(向下的箭頭),此時右擊該設備,選擇啟用即可
蘋果無線滑鼠怎麼突然沒反應了
1、檢查電腦是否具藍牙功能。如果是新的筆記本電腦,首先要查看此筆記本電腦是否具有藍牙功能。因為,目前...
蘋果電腦已經連接了滑鼠為什麼不能用
一、第一種情形:1、重新啟動電腦,讓它從新搜索你的藍牙滑鼠。2、確定你在windows下沒有使用...
蘋果電腦滑鼠沒反應該怎麼辦?
原因有三:1.有線滑鼠損壞。2.USB口損壞,間接意味著主板損壞。3.沒有安裝驅動或驅動崩潰。...
蘋果筆記本觸摸滑鼠沒反應怎麼辦?
一、故障原因:1、可能是觸摸板驅動程序受到損壞或者用戶不小心卸載掉了。2、筆記本觸摸板被關閉了。...
蘋果電腦打開後滑鼠和鍵盤都沒反應怎麼回事?
1.可能是鍵盤和滑鼠連接有問題或本身就有問題。2.建議關機之後,重新插一下鍵盤,注意,如果是US...
蘋果電腦滑鼠鍵盤沒反應怎麼辦
你這種情況我之前遇到,我自己這台新款的蘋果就是這種情況,那時候查了好多論壇,結果這些方法全部過期就是...
C. Python多進程multiprocessing模塊介紹
multiprocessing 是一個支持使用與 threading 模塊類似的 API 來產生進程的包。 multiprocessing 包同時提供了本地和遠程並發操作,通過使用子進程而非線程有效地繞過了 全局解釋器鎖。 因此,multiprocessing 模塊允許程序員充分利用給定機器上的多個處理器。 它在 Unix 和 Windows 上均可運行。
1、multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
2、相關方法
輸出結果如下:
Pool提供了一種快捷的方法,賦予函數並行化處理一系列輸入值的能力,可以將輸入數據分配給不同進程處理(數據並行)。下面的例子演示了在模塊中定義此類函數的常見做法,以便子進程可以成功導入該模塊。這個數據並行的基本例子使用了 Pool 。
將在標准輸出中列印
其中:
(1)p.apply(func [, args [, kwargs]]):在一個池工作進程中執行func( args, kwargs),然後返回結果。需要強調的是:此操作並不會在所有池工作進程中並執行func函數。如果要通過不同參數並發地執行func函數,必須從不同線程調用p.apply()函數或者使用p.apply_async()
(2)p.apply_async(func [, args [, kwargs]]):在一個池工作進程中執行func( args,**kwargs),然後返回結果。此方法的結果是 AsyncResult類的實例,callback是可調用對象,接收輸入參數。當func的結果變為可用時,將理解傳遞給callback。callback禁止執行任何阻塞操作,否則將接收其他非同步操作中的結果。多進程並發!
(3)p.close():關閉進程池,防止進一步操作。如果所有操作持續掛起,它們將在工作進程終止前完成
(4)p.jion():等待所有工作進程退出。此方法只能在close()或teminate()之後調用
D. 什麼是線程(多線程),Python多線程的好處
幾乎所有的操作系統都支持同時運行多個任務,一個任務通常就是一個程序,每一個運行中的程序就是一個進程。當一個程序運行時,內部可能包含多個順序執行流,每一個順序執行流就是一個線程。
線程和進程
幾乎所有的操作系統都支持進程的概念,所有運行中的任務通常對應一個進程(Process)。當一個程序進入內存運行時,即變成一個進程。進程是處於運行過程中的程序,並且具有一定的獨立功能。進程是系統進行資源分配和調度的一個獨立單位。
一般而言,進程包含如下三個特徵:
獨立性:進程是系統中獨立存在的實體,它可以擁有自己的獨立的資源,每一個進程都擁有自己的私有的地址空間。在沒有經過進程本身允許的情況下,一個用戶進程不可以直接訪問其他進程的地址空間。
動態性:進程與程序的區別在於,程序只是一個靜態的指令集合,而進程是一個正在系統中活動的指令集合。在進程中加入了時間的概念。進程具有自己的生命周期和各種不同的狀態,在程序中是沒有這些概念的。
並發性:多個進程可以在單個處理器上並發執行,多個進程之間不會互相影響。
並發(Concurrency)和並行(Parallel)是兩個概念,並行指在同一時刻有多條指令在多個處理器上同時執行;並發才旨在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具有多個進程同時執行的效果。
大部分操作系統都支持多進程並發執行,現代的操作系統幾乎都支持同時執行多個任務。例如,程序員一邊開著開發工具在寫程序,一邊開著參考手冊備查,同時還使用電腦播放音樂……除此之外,每台電腦運行時還有大量底層的支撐性程序在運行……這些進程看上去像是在同時工作。
但事實的真相是,對於一個 CPU 而言,在某個時間點它只能執行一個程序。也就是說,只能運行一個進程,CPU 不斷地在這些進程之間輪換執行。那麼,為什麼用戶感覺不到任何中斷呢?
這是因為相對人的感覺來說,CPU 的執行速度太快了(如果啟動的程序足夠多,則用戶依然可以感覺到程序的運行速度下降了)。所以,雖然 CPU 在多個進程之間輪換執行,但用戶感覺到好像有多個進程在同時執行。
現代的操作系統都支持多進程的並發執行,但在具體的實現細節上可能因為硬體和操作系統的不同而採用不同的策略。比較常用的策略有:
共用式的多任務操作策略,例如 Windows 3.1 和 Mac OS 9 操作系統採用這種策略;
搶占式的多任務操作策略,其效率更高,目前操作系統大多採用這種策略,例如 Windows NT、Windows 2000 以及 UNIX/Linux 等操作系統。
多線程則擴展了多進程的概念,使得同一個進程可以同時並發處理多個任務。線程(Thread)也被稱作輕量級進程(Lightweight Process),線程是進程的執行單元。就像進程在操作系統中的地位一樣,線程在程序中是獨立的、並發的執行流。
當進程被初始化後,主線程就被創建了。對於絕大多數的應用程序來說,通常僅要求有一個主線程,但也可以在進程內創建多個順序執行流,這些順序執行流就是線程,每一個線程都是獨立的。
線程是進程的組成部分,一個進程可以擁有多個線程,一個線程必須有一個父進程。線程可以擁有自己的堆棧、自己的程序計數器和自己的局部變數,但不擁有系統資源,它與父進程的其他線程共享該進程所擁有的全部資源。因為多個線程共享父進程里的全部資源,因此編程更加方便;但必須更加小心,因為需要確保線程不會妨礙同一進程中的其他線程。
線程可以完成一定的任務,可以與其他線程共享父進程中的共享變數及部分環境,相互之間協同未完成進程所要完成的任務。
線程是獨立運行的,它並不知道進程中是否還有其他線程存在。線程的運行是搶占式的,也就是說,當前運行的線程在任何時候都可能被掛起,以便另外一個線程可以運行。
一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程之間可以並發運行。
從邏輯的角度來看,多線程存在於一個應用程序中,讓一個應用程序可以有多個執行部分同時執行,但操作系統無須將多個線程看作多個獨立的應用,對多線程實現調度和管理,以及資源分配。線程的調度和管理由進程本身負責完成。
簡而言之,一個程序運行後至少有一個進程,在一個進程中可以包含多個線程,但至少要包含一個主線程。
歸納起來可以這樣說,操作系統可以同時執行多個任務,每一個任務就是一個進程,進程可以同時執行多個任務,每一個任務就是一個線程。
多線程的好處
線程在程序中是獨立的、並發的執行流。與分隔的進程相比,進程中線程之間的隔離程度要小,它們共享內存、文件句柄和其他進程應有的狀態
因為線程的劃分尺度小於進程,使得多線程程序的並發性高。進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
線程比進程具有更高的性能,這是由於同一個進程中的線程都有共性多個線程共享同一個進程的虛擬空間。線程共享的環境包括進程代碼段、進程的公有數據等,利用這些共享的數據,線程之間很容易實現通信。
操作系統在創建進程時,必須為該進程分配獨立的內存空間,並分配大量的相關資源,但創建線程則簡單得多。因此,使用多線程來實現並發比使用多進程的性能要高得多。
總結起來,使用多線程編程具有如下幾個優點:
進程之間不能共享內存,但線程之間共享內存非常容易。
操作系統在創建進程時,需要為該進程重新分配系統資源,但創建線程的代價則小得多。因此,使用多線程來實現多任務並發執行比使用多進程的效率高。
Python 語言內置了多線程功能支持,而不是單純地作為底層操作系統的調度方式,從而簡化了 Python 的多線程編程。
在實際應用中,多線程是非常有用的。比如一個瀏覽器必須能同時下載多張圖片;一個 Web 伺服器必須能同時響應多個用戶請求;圖形用戶界面(GUI)應用也需要啟動單獨的線程,從主機環境中收集用戶界面事件……總之,多線程在實際編程中的應用是非常廣泛的。
E. 一個Linux多進程編程
1 引言
對於沒有接觸過Unix/Linux操作系統的人來說,fork是最難理解的概念之一:它執行一次卻返回兩個值。fork函數是Unix系統最傑出的成就之一,它是七十年代UNIX早期的開發者經過長期在理論和實踐上的艱苦探索後取得的成果,一方面,它使操作系統在進程管理上付出了最小的代價,另一方面,又為程序員提供了一個簡潔明了的多進程方法。與DOS和早期的Windows不同,Unix/Linux系統是真正實現多任務操作的系統,可以說,不使用多進程編程,就不能算是真正的Linux環境下編程。
多線程程序設計的概念早在六十年代就被提出,但直到八十年代中期,Unix系統中才引入多線程機制,如今,由於自身的許多優點,多線程編程已經得到了廣泛的應用。
下面,我們將介紹在Linux下編寫多進程和多線程程序的一些初步知識。
2 多進程編程
什麼是一個進程?進程這個概念是針對系統而不是針對用戶的,對用戶來說,他面對的概念是程序。當用戶敲入命令執行一個程序的時候,對系統而言,它將啟動一個進程。但和程序不同的是,在這個進程中,系統可能需要再啟動一個或多個進程來完成獨立的多個任務。多進程編程的主要內容包括進程式控制制和進程間通信,在了解這些之前,我們先要簡單知道進程的結構。
2.1 Linux下進程的結構
Linux下一個進程在內存里有三部分的數據,就是"代碼段"、"堆棧段"和"數據段"。其實學過匯編語言的人一定知道,一般的CPU都有上述三種段寄存器,以方便操作系統的運行。這三個部分也是構成一個完整的執行序列的必要的部分。
"代碼段",顧名思義,就是存放了程序代碼的數據,假如機器中有數個進程運行相同的一個程序,那麼它們就可以使用相同的代碼段。"堆棧段"存放的就是子程序的返回地址、子程序的參數以及程序的局部變數。而數據段則存放程序的全局變數,常數以及動態數據分配的數據空間(比如用malloc之類的函數取得的空間)。這其中有許多細節問題,這里限於篇幅就不多介紹了。系統如果同時運行數個相同的程序,它們之間就不能使用同一個堆棧段和數據段。
2.2 Linux下的進程式控制制
在傳統的Unix環境下,有兩個基本的操作用於創建和修改進程:函數fork( )用來創建一個新的進程,該進程幾乎是當前進程的一個完全拷貝;函數族exec( )用來啟動另外的進程以取代當前運行的進程。Linux的進程式控制制和傳統的Unix進程式控制制基本一致,只在一些細節的地方有些區別,例如在Linux系統中調用vfork和fork完全相同,而在有些版本的Unix系統中,vfork調用有不同的功能。由於這些差別幾乎不影響我們大多數的編程,在這里我們不予考慮。
2.2.1 fork( )
fork在英文中是"分叉"的意思。為什麼取這個名字呢?因為一個進程在運行中,如果使用了fork,就產生了另一個進程,於是進程就"分叉"了,所以這個名字取得很形象。下面就看看如何具體使用fork,這段程序演示了使用fork的基本框架:
void main(){
int i;
if ( fork() == 0 ) {
/* 子進程程序 */
for ( i = 1; i <1000; i ++ ) printf("This is child process\n");
}
else {
/* 父進程程序*/
for ( i = 1; i <1000; i ++ ) printf("This is process process\n");
}
}
程序運行後,你就能看到屏幕上交替出現子進程與父進程各列印出的一千條信息了。如果程序還在運行中,你用ps命令就能看到系統中有兩個它在運行了。
那麼調用這個fork函數時發生了什麼呢?fork函數啟動一個新的進程,前面我們說過,這個進程幾乎是當前進程的一個拷貝:子進程和父進程使用相同的代碼段;子進程復制父進程的堆棧段和數據段。這樣,父進程的所有數據都可以留給子進程,但是,子進程一旦開始運行,雖然它繼承了父進程的一切數據,但實際上數據卻已經分開,相互之間不再有影響了,也就是說,它們之間不再共享任何數據了。它們再要交互信息時,只有通過進程間通信來實現,這將是我們下面的內容。既然它們如此相象,系統如何來區分它們呢?這是由函數的返回值來決定的。對於父進程,fork函數返回了子程序的進程號,而對於子程序,fork函數則返回零。在操作系統中,我們用ps函數就可以看到不同的進程號,對父進程而言,它的進程號是由比它更低層的系統調用賦予的,而對於子進程而言,它的進程號即是fork函數對父進程的返回值。在程序設計中,父進程和子進程都要調用函數fork()下面的代碼,而我們就是利用fork()函數對父子進程的不同返回值用if...else...語句來實現讓父子進程完成不同的功能,正如我們上面舉的例子一樣。我們看到,上面例子執行時兩條信息是交互無規則的列印出來的,這是父子進程獨立執行的結果,雖然我們的代碼似乎和串列的代碼沒有什麼區別。
讀者也許會問,如果一個大程序在運行中,它的數據段和堆棧都很大,一次fork就要復制一次,那麼fork的系統開銷不是很大嗎?其實UNIX自有其解決的辦法,大家知道,一般CPU都是以"頁"為單位來分配內存空間的,每一個頁都是實際物理內存的一個映像,象INTEL的CPU,其一頁在通常情況下是4086位元組大小,而無論是數據段還是堆棧段都是由許多"頁"構成的,fork函數復制這兩個段,只是"邏輯"上的,並非"物理"上的,也就是說,實際執行fork時,物理空間上兩個進程的數據段和堆棧段都還是共享著的,當有一個進程寫了某個數據時,這時兩個進程之間的數據才有了區別,系統就將有區別的"頁"從物理上也分開。系統在空間上的開銷就可以達到最小。
下面演示一個足以"搞死"Linux的小程序,其源代碼非常簡單:
void main()
{
for( ; ; ) fork();
}
這個程序什麼也不做,就是死循環地fork,其結果是程序不斷產生進程,而這些進程又不斷產生新的進程,很快,系統的進程就滿了,系統就被這么多不斷產生的進程"撐死了"。當然只要系統管理員預先給每個用戶設置可運行的最大進程數,這個惡意的程序就完成不了企圖了。
2.2.2 exec( )函數族
下面我們來看看一個進程如何來啟動另一個程序的執行。在Linux中要使用exec函數族。系統調用execve()對當前進程進行替換,替換者為一個指定的程序,其參數包括文件名(filename)、參數列表(argv)以及環境變數(envp)。exec函數族當然不止一個,但它們大致相同,在Linux中,它們分別是:execl,execlp,execle,execv,execve和execvp,下面我只以execlp為例,其它函數究竟與execlp有何區別,請通過manexec命令來了解它們的具體情況。
一個進程一旦調用exec類函數,它本身就"死亡"了,系統把代碼段替換成新的程序的代碼,廢棄原有的數據段和堆棧段,並為新程序分配新的數據段與堆棧段,唯一留下的,就是進程號,也就是說,對系統而言,還是同一個進程,不過已經是另一個程序了。(不過exec類函數中有的還允許繼承環境變數之類的信息。)
那麼如果我的程序想啟動另一程序的執行但自己仍想繼續運行的話,怎麼辦呢?那就是結合fork與exec的使用。下面一段代碼顯示如何啟動運行其它程序:
char command[256];
void main()
{
int rtn; /*子進程的返回數值*/
while(1) {
/* 從終端讀取要執行的命令 */
printf( ">" );
fgets( command, 256, stdin );
command[strlen(command)-1] = 0;
if ( fork() == 0 ) {
/* 子進程執行此命令 */
execlp( command, command );
/* 如果exec函數返回,表明沒有正常執行命令,列印錯誤信息*/
perror( command );
exit( errorno );
}
else {
/* 父進程, 等待子進程結束,並列印子進程的返回值 */
wait ( &rtn );
printf( " child process return %d\n",. rtn );
}
}
}
此程序從終端讀入命令並執行之,執行完成後,父進程繼續等待從終端讀入命令。熟悉DOS和WINDOWS系統調用的朋友一定知道DOS/WINDOWS也有exec類函數,其使用方法是類似的,但DOS/WINDOWS還有spawn類函數,因為DOS是單任務的系統,它只能將"父進程"駐留在機器內再執行"子進程",這就是spawn類的函數。WIN32已經是多任務的系統了,但還保留了spawn類函數,WIN32中實現spawn函數的方法同前述UNIX中的方法差不多,開設子進程後父進程等待子進程結束後才繼續運行。UNIX在其一開始就是多任務的系統,所以從核心角度上講不需要spawn類函數。
在這一節里,我們還要講講system()和popen()函數。system()函數先調用fork(),然後再調用exec()來執行用戶的登錄shell,通過它來查找可執行文件的命令並分析參數,最後它么使用wait()函數族之一來等待子進程的結束。函數popen()和函數system()相似,不同的是它調用pipe()函數創建一個管道,通過它來完成程序的標准輸入和標准輸出。這兩個函數是為那些不太勤快的程序員設計的,在效率和安全方面都有相當的缺陷,在可能的情況下,應該盡量避免。
2.3 Linux下的進程間通信
詳細的講述進程間通信在這里絕對是不可能的事情,而且筆者很難有信心說自己對這一部分內容的認識達到了什麼樣的地步,所以在這一節的開頭首先向大家推薦著名作者Richard Stevens的著名作品:《Advanced Programming in the UNIX Environment》,它的中文譯本《UNIX環境高級編程》已有機械工業出版社出版,原文精彩,譯文同樣地道,如果你的確對在Linux下編程有濃厚的興趣,那麼趕緊將這本書擺到你的書桌上或計算機旁邊來。說這么多實在是難抑心中的景仰之情,言歸正傳,在這一節里,我們將介紹進程間通信最最初步和最最簡單的一些知識和概念。
首先,進程間通信至少可以通過傳送打開文件來實現,不同的進程通過一個或多個文件來傳遞信息,事實上,在很多應用系統里,都使用了這種方法。但一般說來,進程間通信(IPC:InterProcess Communication)不包括這種似乎比較低級的通信方法。Unix系統中實現進程間通信的方法很多,而且不幸的是,極少方法能在所有的Unix系統中進行移植(唯一一種是半雙工的管道,這也是最原始的一種通信方式)。而Linux作為一種新興的操作系統,幾乎支持所有的Unix下常用的進程間通信方法:管道、消息隊列、共享內存、信號量、套介面等等。下面我們將逐一介紹。
2.3.1 管道
管道是進程間通信中最古老的方式,它包括無名管道和有名管道兩種,前者用於父進程和子進程間的通信,後者用於運行於同一台機器上的任意兩個進程間的通信。
無名管道由pipe()函數創建:
#include <unistd.h>
int pipe(int filedis[2]);
參數filedis返回兩個文件描述符:filedes[0]為讀而打開,filedes[1]為寫而打開。filedes[1]的輸出是filedes[0]的輸入。下面的例子示範了如何在父進程和子進程間實現通信。
#define INPUT 0
#define OUTPUT 1
void main() {
int file_descriptors[2];
/*定義子進程號 */
pid_t pid;
char buf[256];
int returned_count;
/*創建無名管道*/
pipe(file_descriptors);
/*創建子進程*/
if((pid = fork()) == -1) {
printf("Error in fork\n");
exit(1);
}
/*執行子進程*/
if(pid == 0) {
printf("in the spawned (child) process...\n");
/*子進程向父進程寫數據,關閉管道的讀端*/
close(file_descriptors[INPUT]);
write(file_descriptors[OUTPUT], "test data", strlen("test data"));
exit(0);
} else {
/*執行父進程*/
printf("in the spawning (parent) process...\n");
/*父進程從管道讀取子進程寫的數據,關閉管道的寫端*/
close(file_descriptors[OUTPUT]);
returned_count = read(file_descriptors[INPUT], buf, sizeof(buf));
printf("%d bytes of data received from spawned process: %s\n",
returned_count, buf);
}
}
在Linux系統下,有名管道可由兩種方式創建:命令行方式mknod系統調用和函數mkfifo。下面的兩種途徑都在當前目錄下生成了一個名為myfifo的有名管道:
方式一:mkfifo("myfifo","rw");
方式二:mknod myfifo p
生成了有名管道後,就可以使用一般的文件I/O函數如open、close、read、write等來對它進行操作。下面即是一個簡單的例子,假設我們已經創建了一個名為myfifo的有名管道。
/* 進程一:讀有名管道*/
#include <stdio.h>
#include <unistd.h>
void main() {
FILE * in_file;
int count = 1;
char buf[80];
in_file = fopen("mypipe", "r");
if (in_file == NULL) {
printf("Error in fdopen.\n");
exit(1);
}
while ((count = fread(buf, 1, 80, in_file)) > 0)
printf("received from pipe: %s\n", buf);
fclose(in_file);
}
/* 進程二:寫有名管道*/
#include <stdio.h>
#include <unistd.h>
void main() {
FILE * out_file;
int count = 1;
char buf[80];
out_file = fopen("mypipe", "w");
if (out_file == NULL) {
printf("Error opening pipe.");
exit(1);
}
sprintf(buf,"this is test data for the named pipe example\n");
fwrite(buf, 1, 80, out_file);
fclose(out_file);
}
2.3.2 消息隊列
消息隊列用於運行於同一台機器上的進程間通信,它和管道很相似,事實上,它是一種正逐漸被淘汰的通信方式,我們可以用流管道或者套介面的方式來取代它,所以,我們對此方式也不再解釋,也建議讀者忽略這種方式。
2.3.3 共享內存
共享內存是運行在同一台機器上的進程間通信最快的方式,因為數據不需要在不同的進程間復制。通常由一個進程創建一塊共享內存區,其餘進程對這塊內存區進行讀寫。得到共享內存有兩種方式:映射/dev/mem設備和內存映像文件。前一種方式不給系統帶來額外的開銷,但在現實中並不常用,因為它控制存取的將是實際的物理內存,在Linux系統下,這只有通過限制Linux系統存取的內存才可以做到,這當然不太實際。常用的方式是通過shmXXX函數族來實現利用共享內存進行存儲的。
首先要用的函數是shmget,它獲得一個共享存儲標識符。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int flag);
這個函數有點類似大家熟悉的malloc函數,系統按照請求分配size大小的內存用作共享內存。Linux系統內核中每個IPC結構都有的一個非負整數的標識符,這樣對一個消息隊列發送消息時只要引用標識符就可以了。這個標識符是內核由IPC結構的關鍵字得到的,這個關鍵字,就是上面第一個函數的key。數據類型key_t是在頭文件sys/types.h中定義的,它是一個長整形的數據。在我們後面的章節中,還會碰到這個關鍵字。
當共享內存創建後,其餘進程可以調用shmat()將其連接到自身的地址空間中。
void *shmat(int shmid, void *addr, int flag);
shmid為shmget函數返回的共享存儲標識符,addr和flag參數決定了以什麼方式來確定連接的地址,函數的返回值即是該進程數據段所連接的實際地址,進程可以對此進程進行讀寫操作。
使用共享存儲來實現進程間通信的注意點是對數據存取的同步,必須確保當一個進程去讀取數據時,它所想要的數據已經寫好了。通常,信號量被要來實現對共享存儲數據存取的同步,另外,可以通過使用shmctl函數設置共享存儲內存的某些標志位如SHM_LOCK、SHM_UNLOCK等來實現。