linux 進程間讀寫鎖,Linux系統編程—進程間同步

我們知道,線程間同步有多種方式,比如:信號量、互斥量、讀寫鎖,等等。那進程間如何實現同步呢?本文介紹兩種方式:互斥量和文件鎖。

##互斥量mutex

我們已經知道了互斥量可以用于在線程間同步,但實際上,互斥量也可以用于進程間的同步。為了達到這一目的,可以在pthread_mutex_init初始化之前,修改其屬性為進程間共享。mutex的屬性修改函數主要有以下幾個:

主要應用函數:

pthread_mutexattr_t mattr 類型:用于定義互斥量的屬性

pthread_mutexattr_init函數:初始化一個mutex屬性對象

pthread_mutexattr_destroy函數:銷毀mutex屬性對象 (而非銷毀鎖)

pthread_mutexattr_setpshared函數:修改mutex屬性。

int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);

我們重點看第二個參數:pshared,它有以下兩個取值:

**線程鎖:**PTHREAD_PROCESS_PRIVATE (mutex的默認屬性即為線程鎖,進程間私有)

**進程鎖:**PTHREAD_PROCESS_SHARED

要想實現進程間同步,需要將mutex的屬性改為PTHREAD_PROCESS_SHARED。

#include

#include

#include

#include

#include

#include

#include

#include

struct mt {

int num;

pthread_mutex_t mutex;

pthread_mutexattr_t mutexattr;

};

int main(void)

{

int i;

struct mt *mm;

pid_t pid;

mm = mmap(NULL, sizeof(*mm), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);

memset(mm, 0, sizeof(*mm));

pthread_mutexattr_init(&mm->mutexattr); //初始化mutex屬性對象

pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED); //修改屬性為進程間共享

pthread_mutex_init(&mm->mutex, &mm->mutexattr); //初始化一把mutex瑣

pid = fork();

if (pid == 0) {

for (i = 0; i < 10; i++) {

sleep(1);

pthread_mutex_lock(&mm->mutex);

(mm->num)++;

pthread_mutex_unlock(&mm->mutex);

printf("-child----------num++ %d\n", mm->num);

}

} else if (pid > 0) {

for ( i = 0; i < 10; i++) {

sleep(1);

pthread_mutex_lock(&mm->mutex);

mm->num += 2;

pthread_mutex_unlock(&mm->mutex);

printf("-------parent---num+=2 %d\n", mm->num);

}

wait(NULL);

}

pthread_mutexattr_destroy(&mm->mutexattr); //銷毀mutex屬性對象

pthread_mutex_destroy(&mm->mutex); //銷毀mutex

munmap(mm,sizeof(*mm)); //釋放映射區

return 0;

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

##文件鎖

顧名思義,就是通過文件實現鎖機制。具體來講,是通過借助 fcntl函數來實現鎖機制。當操作文件的進程沒有獲得鎖時,雖然可以打開文件,但無法對文件執行執行read、write操作。

###fcntl函數:

函數原型:

int fcntl(int fd, int cmd, … /* arg */ );

函數作用:

獲取、設置文件訪問控制屬性。

參數介紹:

參數cmd有以下取值:

F_SETLK (struct flock *)設置文件鎖(trylock)

F_SETLKW (struct flock *) 設置文件鎖(lock)W --> wait

F_GETLK (struct flock *)獲取文件鎖

數據類型flock原型如下:

struct flock {

? …

? short l_type; 鎖的類型:F_RDLCK 、F_WRLCK 、F_UNLCK

? short l_whence; 偏移位置:SEEK_SET、SEEK_CUR、SEEK_END

? off_t l_start; 起始偏移:1000

? off_t l_len; 長度:0表示整個文件加鎖

? pid_t l_pid; 持有該鎖的進程ID:(F_GETLK only)

? …

};

###進程間文件鎖示例

多個進程對加鎖文件進行訪問:

#include

#include

#include

#include

#include

#include

void sys_err(char *str)

{

perror(str);

exit(1);

}

int main(int argc, char *argv[])

{

int fd;

struct flock f_lock;

if (argc < 2) {

printf("./a.out filename\n");

exit(1);

}

if ((fd = open(argv[1], O_RDWR)) < 0)

sys_err("open");

f_lock.l_type = F_WRLCK; /*選用寫瑣*/

// f_lock.l_type = F_RDLCK; /*選用讀瑣*/

f_lock.l_whence = SEEK_SET;

f_lock.l_start = 0;

f_lock.l_len = 0; /* 0表示整個文件加鎖 */

fcntl(fd, F_SETLKW, &f_lock);

printf("get flock\n");

sleep(10);

f_lock.l_type = F_UNLCK;

fcntl(fd, F_SETLKW, &f_lock);

printf("un flock\n");

close(fd);

return 0;

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

文件鎖類似于讀寫鎖,依然遵循“讀共享、寫獨占”特性。但是,如果進程不加鎖直接操作文件,依然可訪問成功,但數據勢必會出現混亂。

既然文件鎖可用應用在進程中,那在多線程中,可以使用文件鎖嗎?

答案是不行的。因為多線程間共享文件描述符,而給文件加鎖,是通過修改文件描述符所指向的文件結構體中的成員變量來實現的。因此,多線程中無法使用文件鎖。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453372.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453372.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453372.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

程序員:開汽車,難道我要知道汽車的原理才能把車開好嗎?

一個網友的迷惑&#xff1a; 我工作&#xff15;年了&#xff0c;一直做&#xff2a;&#xff12;&#xff25;&#xff25;的項目&#xff0c;前幾天去面試&#xff0c;一個人問我JDBC有幾種連接方式&#xff0c;這個問題這么多年以來我從來沒有遇見過&#xff0c;不知道大家 …

杭州某知名xxxx公司急招大量java以及大數據開發工程師

因公司戰略以及業務拓展&#xff0c;收大量java攻城獅以及大數據開發攻城獅. 職位信息&#xff1a; java攻城獅: https://job.cnblogs.com/offer/56032 大數據開發攻城獅: https://job.cnblogs.com/offer/56033 歡迎博客園的XDJM自薦和推薦&#xff01; 此招聘長期有效 歡迎留言…

35.6. /etc/dnsmasq.d/dnsmasq.address.conf

vim /etc/dnsmasq.d/dnsmasq.address.confaddress/www.mydomain.com/172.16.0.254deny domain address/www.facebook.com/127.0.0.1 address/www.google.com/127.0.0.135.6.1. 域名劫持 將域名解析到錯誤的地址&#xff0c;這樣可以屏蔽一些網站。 address/www.facebook.com/12…

請求地址操作中的(int*)

例如 float b3.14,*a&b; int *p(int *)a; 表示將指針a的類型轉換為整型指針再賦給p。

linux初始化內存盤卡住,Linux系統內存磁盤初始化技術詳細解析

轉自&#xff1a;http://m.zol.com.cn/article/1271270.html?viaindexLinux內存初始化技術(initrd)用于支持兩階段的系統引導過程&#xff0c;是在系統啟動過程中被掛載的臨時root文件系統(譯者注&#xff1a;這里的root文件系統是指的根文件系統)。initrd包含很多可執行程序和…

程序員是程序中的臨時變量,用完扔掉?

今天看到某人從墳墓里刨出的文章&#xff0c;挺有意思的。 程序員&#xff0c;到了一定年齡&#xff0c;如果沒有機會轉到領導級&#xff0c;至少是項目經理&#xff0c;能獨立領導團隊完成項目&#xff0c;還是停留在編碼的層次&#xff0c;那么被迫離開的危險會是很高的&…

屬性依賴注入

1.依賴注入方法 手動裝配和自動裝配 2.手動裝配 2.1 基于xml裝配 2.1.1 構造方法 <!-- 構造方法注入<constructor-arg>name:參數名type:類型value: --> <bean id"user" class"g_xml.constructor.User"><constructor-arg name"id…

windows下實現自己的第一個python腳本文件并.exe運行

前言 python可以做很多事情&#xff0c;比如知乎上的回答&#xff0c;每天來到公司都要打開AS&#xff0c; QQ和微信,為了省事決定用python寫一個簡單的腳本來實現。。腳本內容只有幾行,python的代碼真的好簡潔。。。 import os os.startfile("C:\Program Files (x86)\Ten…

C++中引用()基礎認識

對于習慣使用C進行開發的朋友們&#xff0c;在看到c中出現的&符號&#xff0c;可能會犯迷糊&#xff0c;因為在C語言中這個符號表示了取地址符&#xff0c;但是在C中它卻有著不同的用途&#xff0c;掌握C的&符號&#xff0c;是提高代碼執行效率和增強代碼質量的一個很好…

linux無法訪問443端口,linux – 為什么我無法在Ubuntu上ping端口443?

我通過iptables打開了端口443&#xff1a;pkts bytes target prot opt in out source destination45 2428 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/06 1009 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80141 10788 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:220 0 AC…

MediaWiki安裝配置(Linux)【轉】

閱讀目錄 2.1 本例子的安裝環境如下&#xff1a;轉自&#xff1a;http://blog.csdn.net/gao36951/article/details/43965527 版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 目錄(?)[-] 1MediaWiki簡介 2MediaWiki安裝21 本例子的安裝環境如…

提高編程水平的一段必經之路,研讀官方文檔

剛才看了 論壇里 jinxfei 的十年總結&#xff08;14&#xff09;&#xff1a;從CS轉向BS, 說實話&#xff0c;大部分內容我沒有太仔細的看&#xff0c;不過如下的一段引起了我的注意&#xff1a; 真正讓我心里有底的&#xff0c;還是在看了官方文檔之后&#xff1a;http://str…

在Asp.net core返回PushStream

最近用asp.net core webapi實現了一個實時視頻流的推送功能&#xff0c;在Asp.net中&#xff0c;這個是通過PushStreamContent來實現的。 基于對asp.net core的知識&#xff0c;隨手寫了一個&#xff08;要求控制器繼承自Controller基類&#xff09; [HttpGet] public async Ta…

順序棧的代碼實現

棧是一種限定只在表尾進行插入或刪除操作的線性表&#xff0c;棧也是線性表。表頭稱為棧的底部,表尾稱為棧的頂部,表為空稱為空棧。 棧又稱為后進先出的線性表,棧也有兩種表示:順序棧與鏈式棧。順序棧是利用一組地址連續的存儲單元。依次存放從棧底到棧頂的數據元素。 #includ…

Linux5觀察doc目錄并截屏,linux截屏命令

linux系統我們有時需要用到截屏功能&#xff0c;下面由學習啦小編為大家整理了linux截屏命令的相關知識&#xff0c;希望對大家有幫助!linux截屏命令詳解import檢測&#xff1a;import --versionimprot安裝&#xff1a;sudo apt-get install importimport常用命令&#xff1a;1…

eclipse+tomcat開發web程序

環境&#xff1a;windows 7Eclipse Java EE IDE for Web Developerstomcat 7.02 插件&#xff1a;tomcatPluginV321.zip 一.配置Tomcat插件 我們創建一個myplugins文件夾用于存放插件&#xff0c;myplugins位于D:/Program Files/J2EE目錄下。eclipse安裝路徑為&#xff1a;D:/P…

LoadRunner參數包含逗號

loadrunner的參數以逗號區分&#xff0c; 如果參數本身包含逗號&#xff0c;則會報錯 使用","將逗號包起來即可&#xff0c;如下圖 轉載于:https://www.cnblogs.com/cherrysu/p/8507649.html

軟件創業見聞

今天應一位朋友的邀請&#xff0c;過去蹭了個飯吃&#xff0c;順便坐了一個下午在聊著。這位老哥是一家軟件公司的老板&#xff0c;原來是從硬件銷售轉型到做軟件這一塊。因為說到軟件這一塊&#xff0c;我就很想了解一下這位老哥對于2009年的大勢是怎么看的&#xff0c;在2009…

如何采用設置標志的方法來區分循環隊列的滿和空

設立一個標志位,比如說是flag 最開始時隊列為空,設flag0 當入隊的時候讓flag1 出隊的時候flag0 然后再加上判斷隊頭隊尾指針是否重合 重合,且flag0,則為空 重合且flag1,則為滿

linux內核定義的常用信號6,linux復習

(3)設定apache服務器的網頁根目錄&#xff1a;/home/htdocs(4)在此apache服務器上設定一個目錄/home/htdocs/inside,且此目錄只允許IP地址為192.168.1.5的主機訪問(5)定義apache服務器以獨立進程的方式運行2、某系統管理員需每天做一定的重復工作&#xff0c;請按照下列要求&am…