多程序程式設計的核心技術是程序間的同步——通訊與互斥訪問
一、程序間的通訊
1、管道
2、system v訊號量
3、共享記憶體
4、訊息佇列
5、訊號
6、套接字
二、程序間對資源的互斥訪問
條件變數
訊號量讀寫鎖(記錄鎖)
自旋鎖原子鎖(順序鎖)
記錄鎖:
int fcntl(int fd, int cmd, struct flock* flockptr);
cmd可以是f_getlk、f_setlk或f_setlkw。
f_getlk:檢視是否有其它程序鎖與flockptr所描述的衝突,如果存在衝突,則將其資訊寫到flockptr。反之只改寫flockptr.l_type為f_unlck。flock結構體定義:f_setlk:設定或清楚flockptr描述的鎖。若跟已有的鎖衝突,則返回-1並將errno設定為eacces或者eagain。
f_setlkw:作用同上。但若有衝突的鎖,則阻塞等待直到與其它鎖衝突消失或被訊號中斷。被訊號中斷返回時,返回-1並設定errno為eintr。
[cpp]view plain
copy
struct
flock
;
例如給某個檔案上寫鎖:
[cpp]view plain
copy
flock lk;
lk.l_type = f_wrlck;
lk.l_whence = seek_set;
lk.l_start = 0;
lk.l_len = 0;
fcntl(fd,f_setlk,&lk);
理解:1、當檔案無鎖的時候,任何程序都能上讀鎖或寫鎖。
2、當檔案被a程序上了讀鎖的時候,其它任何程序都可以上讀鎖,但不能上寫鎖!(很容易理解,a程序上了讀鎖(需要讀此檔案),此時其它程序也上讀鎖不會對a做成影響。但如果其它程序要上寫鎖(需要對檔案進行寫操作),那會影響到a的進行,因為寫操作會修改原檔案!!)
3、當檔案被a程序上了寫鎖,其它任何程序都不能上寫或讀鎖。(因為a程序上寫鎖(代表需要寫此檔案),如果此時其它程序讀此檔案的話必定受影響,其它程序寫操作的話,雙方都受影響。)
核心中理解記錄鎖:
在系統在每個檔案vnode中(每個開啟檔案都有乙個v節點結構)有乙個記錄鎖鏈表:
鍊錶中元素有四個字段:
1、鎖的flag。
2、鎖的起始偏移量(絕對偏移量)。
3、鎖的長度(為0則代表直到檔案最後——跟隨檔案大小而改變)。
4、程序id號。
注意第4個字段,由於檔案鎖引數是記錄在系統v節點表裡的記錄鎖鏈表裡的,而fork子程序和父程序具有不同的程序id號,因此子程序自然也不繼承父程序的檔案鎖。同理exec
前後具有相同程序id號,因此繼承相同的檔案鎖(除非檔案標記了close_on_exec,exec之後自動關閉檔案,自然同時關閉檔案鎖)。
強制鎖和建議鎖:
1、強制鎖會影響到其它程序的讀寫操作:open、read、write等。
例如:a程序對某檔案某部分加了強制寫鎖,其它程序都不能對那部分進行上鎖或讀寫。
2、建議鎖只會影響其它程序的上鎖操作,而不會限制實際的io。
例如:a程序對某檔案某部分加了強制寫鎖,其它程序不能對那部分上鎖,但還是可以對其讀寫的(但這樣無視鎖的做法是不可取的)
注意:在linux中fcntl預設上的是建議鎖!!!
協同程序:
建議鎖並不強制限制i/o,因此當所有程序都自覺使用建議鎖,並根據建議鎖的情況考慮是否讀寫,才能發揮建議鎖的作用。這樣些遵循建議鎖的程序稱為協同程序。
記錄鎖的關閉:
無論用dup複製多少個檔案描述符,只要有其中乙個被close了,則此程序的所有鎖都被關閉了。
記錄鎖引發的問題:
死鎖問題:兩個程序互相阻塞等待對方持有的鎖,最嚴重後果是兩程序永遠阻塞成死鎖。例如:a程序有a鎖,b程序有b鎖,a試圖用f_setlkw設鎖到有b鎖的資源,同時b也使用f_setlkw設鎖要有a鎖的資源,後果是兩個傻傻地阻塞下去。(但現在系統會檢測死鎖,並將出錯資訊通知其中乙個程序)。
C 多程序檔案讀寫的鎖處理
隨著服務程序的增多,光憑程序內的執行緒同步已經不能滿足現在的需求,導致多程序同時寫入同乙個檔案時,一樣提示檔案被占用的問題。在這種場景下,跨程序級的鎖是不可避免的。在.net提供的參考中,程序鎖都繼承了system.threading.waithandle類 而在本文中針對單個檔案同一時間僅允許單個...
程序(讀寫鎖)
併發操作 對於某一資料,多使用者可以併發的讀取資料,但是同時只可以有乙個使用者進行修改操作。讀寫鎖 read write lock 一 綜述 在一些程式中存在讀者寫者問題,也就是說,對某些資源的訪問會 存在兩種可能的情況,一種是訪問必須是排它行的,就是獨佔的意思,這稱作寫操作 另一種情況就是訪問方式...
多程序中的程序鎖(互斥鎖)
以下例項中 import threading lock threading.lock num 0def work1 asd global num for i in range asd num 1print 在當前的執行緒修改過後的num是 num defwork2 asd global num fo...