將讀寫鎖放到共享內存,實現進程之間對于同一文件的讀寫操作

思路

  • 將讀寫鎖和讀寫鎖的屬性以及一個用于存儲共享內存的地址的int型變量三者封裝成一個struct結構
  • 將這個結構體放到共享內存中,以及將讀寫鎖的屬性設置成全局性質,然后使用這個屬性初始化鎖,以及將鎖的地址關聯到結構體的內存地址這個變量
  • 定義一個銷毀函數,用于退出進程的時候,將內存空間銷毀,以及刪除對應的變量
  • 定義讀寫函數,讀函數讀取文件的內容,輸出文件的內容;寫函數,以追加的方式,向指定文件中寫入數據
  • 測試:使用fork創建父子兩個進程,定義一個for循環,循環5次之后,退出循環并且執行銷毀函數。
  • 在使用讀寫函數之前需要對于鎖執行相關的操作,比如加讀鎖,加寫鎖,以及執行完讀寫文件函數之后去掉鎖

代碼

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cassert>
#include <pthread.h>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstring>/***  返回一片共享內存標識符,用于后續獲取該共享內存,以及銷毀該共享內存*/
namespace hhh{namespace hhh{class mutex_function{public:mutex_function() = default;// 定義進程鎖結構體typedef struct mutex_struct{pthread_rwlock_t lock;pthread_rwlockattr_t lock_attr;int memory_addr;}mutex_struct_t;int create_share_memory_id(const int index_of_key,size_t md5){const char* file_path = "./";key_t id = ftok(file_path,md5);const int share_memory_id = shmget(id,md5,IPC_CREAT | 0666);if (share_memory_id == -1){std::cout << "share_memory_id error!\n" << std::endl;exit(EXIT_FAILURE);}else{return share_memory_id;}}// 初始化進程鎖結構體int init_mutex_struct(mutex_struct_t* mutex_ptr){pthread_rwlockattr_init(&(mutex_ptr->lock_attr));pthread_rwlockattr_setpshared(&(mutex_ptr->lock_attr),PTHREAD_PROCESS_SHARED);pthread_rwlock_init(&(mutex_ptr->lock),&(mutex_ptr->lock_attr));return 0;}// 在共享內存上定義進程鎖結構體并且返回其位置mutex_struct_t* mutex_struct_addr(const int index){int memory_id = create_share_memory_id(index,sizeof (mutex_struct_t));mutex_struct_t * share_ptr = (mutex_struct_t* )shmat(memory_id, 0, 0);if (share_ptr == (void *)-1){std::cout << "share_ptr error!\n" << std::endl;exit(EXIT_FAILURE);}share_ptr->memory_addr = memory_id;assert(init_mutex_struct(share_ptr)== 0);return share_ptr;}// 銷毀進程鎖結構體,利用其memory_addr變量索引到其占用的共享內存并銷毀const int destroy_mutex_memory(mutex_struct_t * mutex_struct){pthread_rwlock_destroy(&(mutex_struct->lock));pthread_rwlockattr_destroy(&(mutex_struct->lock_attr));assert(shmctl(mutex_struct->memory_addr,IPC_RMID, nullptr) == 0);return 0;}public:mutex_struct_t* mutex_struct_ptr;};}//namespace hhh
}//namespace hhh//read file
void read_file(const std::string file_name,int id){std::ifstream fp(file_name,std::ios::binary);std::stringstream ss;ss << fp.rdbuf();std::cout << "線程"<< id << "搶占了資源,輸出:" << ss.str() << std::endl;sleep(3);std::cout << "線程"<< id << "釋放了資源...\n" << std::endl;fp.close();
}
//write file
void write_file(const char *file_name,char *str,int id){FILE *fd = fopen(file_name,"a+");if (fd == nullptr){printf("fd is nullptr and open file fail\n");} else{std::cout <<"線程"<< id << "搶占了資源" << std::endl;fwrite(str,strlen(str),1,fd);char *next = "\0";fwrite(next,strlen(next),1,fd);sleep(5);std::cout << "線程"<< id << "釋放了資源...\n" << std::endl;}fclose(fd);
}
int main(){std::string file_name = "/home/gsc/Projects/1.txt";char * str1 = "progress 1";// 創建自定義進程鎖hsm::hal::mutex_function mutex_function_object;mutex_function_object.mutex_struct_ptr = mutex_function_object.mutex_struct_addr(111);// 創建新進程int id = fork();assert(id >= 0);// 設置循環次數for (int i = 0; i < 5; ++i) {if (id > 0) {  // 父進程// 讀鎖
//            pthread_rwlock_rdlock(&(mutex_function_object.mutex_struct_ptr->lock));
//            read_file(file_name,getpid());
//            pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));// 寫鎖pthread_rwlock_wrlock(&(mutex_function_object.mutex_struct_ptr->lock));write_file(file_name.c_str(),str1,getpid());pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));} else {  // 子進程// 讀鎖
//            pthread_rwlock_rdlock(&(mutex_function_object.mutex_struct_ptr->lock));
//            read_file(file_name,getpid());
//            pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));// 寫鎖pthread_rwlock_wrlock(&(mutex_function_object.mutex_struct_ptr->lock));write_file(file_name.c_str(),str1,getpid());pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));}}// 等待循環完畢sleep(1);// 循環完畢,銷毀進程鎖,釋放申請的共享內存if (id > 0) {  // 父進程mutex_function_object.destroy_mutex_memory((mutex_function_object.mutex_struct_ptr));mutex_function_object.mutex_struct_ptr = nullptr;printf("父進程釋放資源完畢\n");}return 0;
}

?

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

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

相關文章

Android Studio 查看頁面布局層次結構

Android Studio有個可以查看手機上app頁面布局層次結構的工具。可以協助我們對布局進行優化&#xff0c;去掉沒有必要的節點等&#xff0c;通過這個工具可以清晰的看見頁面整個結構&#xff1b;廢話少說直接上圖&#xff0c;再說過程。 這就是我們想要看到的&#xff0c;每個節…

Java web后端 第一章框架搭建

Redis 通用Mapper 通用Mapper->MyBatis動態SQL封裝包,增刪改查 0 SQL語句 PageHelper PageHelper–>實現分頁操作,不需要limit,直接使用靜態方法 電商系統技術特點 分布式(數據很多,一臺電腦存儲一部分數據) 高并發,集群(并發量很高,后臺不只一個電腦) ,海量數據 主…

進程鎖 讀寫文件的小例子 C++代碼

代碼 #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <cassert> #include <pthread.h> #include <cstdio> #include <cstdlib> #include <fstream> #include <io…

Java 中sleep()與wait()的區別

目錄一、原理不同二、鎖的處理機制不同三、使用的區域不同四、異常捕獲不同五、總結一、原理不同 sleep()是Thread類的靜態方法&#xff0c;是線程用來控制自身流程的&#xff0c;它會使此線程暫停執行指定的時間&#xff0c;而把執行機會讓給其他的線程&#xff0c;等到計時時…

android--地圖定位打卡

獲取位置信息 1)位置信息 GPS衛星定位,在室外適用 基站(3個基站交叉,鎖定手機位置)–基站定位不平均,有些地方實現不了3點定位 網絡定位–通過手機IP地址,去鎖定位置(消耗流量,對網絡有要求) 谷歌地圖的大致實現思路(通用) 2)實現定位功能的重要類 在百度地圖和高德地圖中不…

Android 將整形顏色值轉換成String類型

轉換方法&#xff1a; val hexColor String.format("#%06X", [0xFFFFFF or intColor]);轉換結果&#xff1a; #F2EADA

MacOS 的 zsh 和 bash 切換

目錄一、從 bash 切換到 zsh1、使用系統自帶的 zsh2、使用第三方的 zsh2.1、Clone代碼到本地2.2、備份你已存在的 ~/.zshrc 文件2.3、新建一份新的 zsh 配置文件2.4、改變默認的shell腳本二、從 zsh 切換回 bash三、zsh 和 bash 的環境變量zsh、bash 都是shell&#xff0c;zsh …

android--在命令行中生成Android的數字證書keystore文件

標題 生成 密鑰口令為 13458977480 密鑰庫口令為 13458977480 存放位置 查看證書的相關資料

linux查看系統日志

cd /var/log/gscubuntu:/var/log$ tail -f syslog

IDEA 創建 SpringBoot 項目

目錄一、新建Springboot項目第一步&#xff1a;新建一個Springboot項目第二步&#xff1a;選擇項目模板第三步&#xff1a;設置項目配置第四步&#xff1a;設置項目依賴第五步&#xff1a;設置項目名稱及路徑第六步&#xff1a;創建完成二、測試及運行1、測試代碼2、設置默認端…

VC++軟件

一個main fatal error LNK1169: 找到一個或多個多重定義的符號–報錯 一個項目即一個程序&#xff0c;多個文件只能有一個main函數 刪除掉多余的main 控制臺按enter鍵閃退 在代碼中加上 #include<stdlib.h> getchar();//讓控制臺停留 system("pause");//讓…

IDEA 將 SpringBoot 項目打包成jar

目錄一、打包配置1、File -> Project Structure2、Project Structure3、設置啟動類及META-INF4、設置打包輸出目錄二、打包1、Build -> Artifacts2、Build三、查看打包文件四、運行新建SpringBoot項目&#xff1a;IDEA 創建 SpringBoot 項目 一、打包配置 1、File -> …

2014年考研英語一完型填空知識點

單詞 單詞釋意commitv犯罪sufficientlyadv足夠gainfuladj有收益的socioeconomicadj社會經濟的discontentn/v不滿意householdn家庭supervisionn監督offensiveadj冒犯的conditionn狀態casualadj隨意的causaladj因果關系的establishedadj已確立,公認的interactionn相互作用或影響…

如何查看軟連接,以及相關注意事項

使用命令 ls -il 圖片顯示 參考鏈接 Linux 命令之軟連接詳解Linux軟連接 查看/創建/刪除

Git SSH key配置

一、檢查本地Git配置 用如下命令&#xff08;如未特別說明&#xff0c;所有命令均默認在Git Bash工具下執行&#xff09;檢查一下用戶名和郵箱是否配置&#xff08;github支持我們用用戶名或郵箱登錄&#xff09;&#xff1a; git config --global --list 顯示信息如下&#…

2014年英語一閱讀理解Text1

單詞解釋chancellorn總理upfrontadj坦率的eligibleadj有資格的,合格的fortnightlyadv兩星期一次的sign on辦理reformn改革subsidisev補助zealn熱情taxpayern納稅人claimantn(因失業)領取救濟金者skip down邊跳邊走prospectn前景psychologicallyadv心理上地excludev不包括crucia…

HTTPS 工作原理

一、簡介 HTTPS對于客戶端開發人員來說并沒有什么需要特別注意的地方&#xff0c;因為代碼和寫HTTP請求時并沒有什么兩樣。但也正是因為這個原因&#xff0c;導致許多客戶端開發人員對HTTPS并不了解&#xff0c;只知道它是安全的加密網絡傳輸&#xff0c;對其具體的工作原理卻一…

解決VM虛擬機中ubuntu系統上不了網的問題

最簡單的方式 關閉虛擬機在對應的虛擬機上右鍵&#xff0c;點擊設置&#xff0c;找到網絡適配器&#xff0c;點擊移除&#xff0c;再次點擊添加&#xff0c;將網絡適配器再次添加回來&#xff0c;點擊確定重啟虛擬機如果第一種方式解決不了問題&#xff0c;請使用第二種方式 …

Android Glide圖片加載框架(一)基本用法

文章目錄一、前言二、簡介三、基本用法第一步&#xff1a;調用 Glide.with() 方法創建加載圖片的實例第二步&#xff1a;調用 load() 方法指定待加載的圖片資源第三步&#xff1a;調用 into() 方法綁定顯示控件總結四、擴展用法1、占位圖2、指定圖片格式3、指定圖片大小Android…