進程線程間的通信:2024/2/22

作業1:代碼實現線程互斥機制

代碼:

#include <myhead.h>//臨界資源
int num=10;//創建一個互斥鎖
pthread_mutex_t mutex;//任務一
void *task1(void *arg)
{//獲取鎖資源pthread_mutex_lock(&mutex);num=123;sleep(3);printf("task1:num=%d\n",num);//釋放鎖資源pthread_mutex_unlock(&mutex);//退出線程pthread_exit(NULL);
}
//任務二
void *task2(void *arg)
{//獲取鎖資源pthread_mutex_lock(&mutex);num++;sleep(1);printf("task2:num=%d\n",num);//釋放鎖資源pthread_mutex_unlock(&mutex);//退出線程pthread_exit(NULL);
}
/*************************主程序************************/
int main(int argc, const char *argv[])
{//初始化互斥鎖pthread_mutex_init(&mutex,NULL);//創建兩個線程pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid1 error\n");return -1;}printf("tid1=%#lx tid2=%#lx\n",tid1,tid2);//回收資源pthread_join(tid1,NULL);pthread_join(tid2,NULL);//銷毀互斥鎖pthread_mutex_destroy(&mutex);return 0;
}

效果圖:

作業2:代碼實現無名信號量的線程同步機制

代碼:

#include <myhead.h>//定義一個無名信號量
sem_t sem1;
sem_t sem2;
sem_t sem3;
//任務1
void *task1(void *arg)
{int num=4;while(num--){//申請資源sem_wait(&sem3);sleep(1);printf("A");fflush(stdout);           //刷新緩沖區//釋放資源sem_post(&sem1);}//退出線程pthread_exit(NULL);}
//任務2
void *task2(void *arg)
{int num=4;while(num--){//申請資源sem_wait(&sem1);sleep(1);printf("B");fflush(stdout);           //刷新緩沖區//釋放資源sem_post(&sem2);}//退出線程pthread_exit(NULL);}
//任務3
void *task3(void *arg)
{int num=4;while(num--){//申請資源sem_wait(&sem2);sleep(1);printf("C");fflush(stdout);           //刷新緩沖區//釋放資源sem_post(&sem3);}//退出線程pthread_exit(NULL);}
/*********************主程序********************/
int main(int argc, const char *argv[])
{//初始化無名信號量sem_init(&sem1,0,0);sem_init(&sem2,0,0);sem_init(&sem3,0,1);//創建三個線程pthread_t tid1,tid2,tid3;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task3,NULL) != 0){printf("create tid3 error\n");return -1;}//回收資源pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);//銷毀無名信號量sem_destroy(&sem1);sem_destroy(&sem2);sem_destroy(&sem3);puts("");return 0;
}

效果圖:

作業3:代碼實現條件變量的線程同步機制

代碼:

#include <myhead.h>
//定義條件變量
pthread_cond_t cond;//定義互斥鎖變量
pthread_mutex_t mutex;//生產者
void *task1(void *arg)
{int num=3;while(num--){sleep(1);printf("%#lx:摘了一個蘋果\n",pthread_self());//喚醒一個進程pthread_cond_signal(&cond);}//退出線程pthread_exit(NULL);
}
//消費者
void *task2(void *arg)
{//獲取鎖資源pthread_mutex_lock(&mutex);//進入等待隊列pthread_cond_wait(&cond,&mutex);printf("%#lx:吃了一個蘋果\n",pthread_self());//釋放鎖資源pthread_mutex_unlock(&mutex);//退出進程pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{//初始化條件變量pthread_cond_init(&cond,NULL);//初始化互斥鎖變量pthread_mutex_init(&mutex,NULL);//創建生產者與消費者線程pthread_t tid1,tid2,tid3,tid4;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task2,NULL)!=0){printf("create tid3 error\n");return -1;}if(pthread_create(&tid4,NULL,task2,NULL)!=0){printf("create tid4 error\n");return -1;}//回收資源pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);pthread_join(tid4,NULL);//銷毀條件變量pthread_cond_destroy(&cond);//銷毀互斥鎖pthread_mutex_destroy(&mutex);return 0;
}

效果圖:

作業4:代碼實現無名管道的通信

代碼:

#include <myhead.h>
int main(int argc, const char *argv[])
{//創建管道文件int pipefd[2]={0};if(pipe(pipefd)==-1){perror("pipe error");return -1;}//創建子進程pid_t pid=fork();if(pid>0){//父進程進行寫操作//關閉管道讀端close(pipefd[0]);char wbuf[128]="";while(1){//清空數組內容bzero(wbuf,sizeof(wbuf));//從終端輸入數據fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//開始向管道文件中寫入數據write(pipefd[1],wbuf,strlen(wbuf));//判斷寫入的數據if(strcmp(wbuf,"quit")==0){break;}}//關閉管道寫端close(pipefd[1]);//等待回收子進程wait(NULL);}else if(pid==0){//子進程進行讀操作//關閉管道寫端close(pipefd[1]);char rbuf[128]="";while(1){//清空數組內容bzero(rbuf,sizeof(rbuf));//從管道文件中讀取數據read(pipefd[0],rbuf,sizeof(rbuf));printf("從父進程傳來的數據:%s\n",rbuf);//判斷寫入的數據if(strcmp(rbuf,"quit")==0){break;}}//關閉管道讀端close(pipefd[0]);//退出子進程exit(EXIT_SUCCESS);}else{perror("pid error");return -1;}return 0;
}

效果圖:

作業5:代碼實現有名管道的通信

代碼:

create.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//創建一個管道文件if(mkfifo("./myfifo",0664)==-1){perror("mkfifo error");return -1;}getchar();          //阻塞system("rm myfifo");return 0;
}

snd.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//打開管道文件int wfd=-1;//以只寫的形式打開管道文件if((wfd=open("./myfifo",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//從終端輸入數據printf("請輸入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//將數據寫入管道文件write(wfd,wbuf,strlen(wbuf));//結束輸入的條件if(strcmp(wbuf,"quit")==0){break;}}//關閉文件close(wfd);return 0;
}

rec.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//打開管道文件int rfd=-1;//以只讀形式打開文件if((rfd=open("./myfifo",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空數組bzero(rbuf,sizeof(rbuf));//從管道讀取數據read(rfd,rbuf,sizeof(rbuf));//輸出結果printf("收到的數據為:%s\n",rbuf);//退出條件if(strcmp(rbuf,"quit")==0){break;}}//關閉文件close(rfd);return 0;
}

效果圖:

作業6:使用有名管道完成兩個進程的相互通信

(提示:可以使用多進程或多線程完成)

代碼:

create.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//創建兩個管道文件if(mkfifo("./myfifo1",0664)==-1){perror("mkfifo error");return -1;}if(mkfifo("./myfifo2",0664)==-1){perror("mkfifo error");return -1;}getchar();          //阻塞system("rm myfifo1");system("rm myfifo2");return 0;
}

snd.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//創建一個進程pid_t pid=fork();if(pid>0){//父進程發送數據//打開管道文件int wfd=-1;//以只寫的形式打開管道文件if((wfd=open("./myfifo1",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//從終端輸入數據printf("請輸入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//將數據寫入管道文件write(wfd,wbuf,strlen(wbuf));//結束輸入的條件if(strcmp(wbuf,"quit")==0){break;}}//關閉文件close(wfd);}else if(pid==0){//子進程接收數據//打開管道文件int rfd=-1;//以只讀形式打開文件if((rfd=open("./myfifo2",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空數組bzero(rbuf,sizeof(rbuf));//從管道讀取數據read(rfd,rbuf,sizeof(rbuf));//輸出結果printf("收到的數據為:%s\n",rbuf);//退出條件if(strcmp(rbuf,"quit")==0){break;}}//關閉文件close(rfd);}else{perror("pid error");return -1;}return 0;
}

rec.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//創建一個進程pid_t pid=fork();if(pid>0){//父進程接收數據//打開管道文件int rfd=-1;//以只讀形式打開文件if((rfd=open("./myfifo1",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空數組bzero(rbuf,sizeof(rbuf));//從管道讀取數據read(rfd,rbuf,sizeof(rbuf));//輸出結果printf("收到的數據為:%s\n",rbuf);//退出條件if(strcmp(rbuf,"quit")==0){break;}}//關閉文件close(rfd);}else if(pid==0){//子進程發送數據//打開管道文件int wfd=-1;//以只寫的形式打開管道文件if((wfd=open("./myfifo2",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//從終端輸入數據printf("請輸入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//將數據寫入管道文件write(wfd,wbuf,strlen(wbuf));//結束輸入的條件if(strcmp(wbuf,"quit")==0){break;}}//關閉文件close(wfd);}else{perror("pid error");return -1;}return 0;
}

效果圖:

作業7:思維導圖

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

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

相關文章

PacketSender-用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序

PacketSender-用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序 PacketSender是一款開源的用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序&#xff0c;作者為dannagle。 其官網地址為&#xff1a;https://packetsender.com/&#xff0c;Github源代碼地址&#xff1a;htt…

【AI繪畫工具分別有哪些?】

目前有許多AI繪畫工具可供選擇&#xff0c;以下列舉了一些常見的AI繪畫工具&#xff1a; 1. DeepArt.io&#xff1a;該工具使用深度學習算法生成藝術風格的圖像&#xff0c;并可以將輸入圖像與指定的藝術風格進行合并。 2. Prisma&#xff1a;這是一款非常流行的AI繪畫應用&a…

SQL Server —— While語句循環

一&#xff1a;簡介 while 循環是有條件的循環控制語句。滿足條件后&#xff0c;再執行循環體中的SQL語句。 while: break, 如果有多條語句可以在while后面添加begin-end。關于while的語法 while(條件) -- begin -- 語句1 -- 語句2 -- break 根據情況是否添加break -- end 二…

leetcode日記(32)字符串相乘

做了很久很久……真的太繁瑣了&#xff01;&#xff01; class Solution { public:string multiply(string num1, string num2) {string s;string str;if (num1 "0" || num2 "0") return "0";for(int inum2.size()-1;i>0;i--){int c2num2[…

Open CASCADE學習|全局屬性

目錄 1、概念解釋 質心&#xff1a; 重心&#xff1a; 慣性矩&#xff1a; 慣性矩陣&#xff1a; 主慣性矩&#xff1a; 靜態慣性矩&#xff1a; 2、API 1、概念解釋 質心&#xff1a; 質心是質量中心的簡稱&#xff0c;指物質系統上被認為質量集中于此的一個假想點。…

Qt:tabWidget控件

一、tabWidget用來做什么 tabWidget控件用來進行不同控件頁面的跳轉&#xff0c; 二、控件的一些函數功能 添加一個頁面&#xff0c;返回index int addTab(QWidget *widget, const QString &); int addTab(QWidget *widget, const QIcon& icon, const QString &…

pytest教程-11-初識fixture

領取資料&#xff0c;咨詢答疑&#xff0c;請?wei: June__Go 上一小節我們學習了使用allure生成html測試報告的方法&#xff0c;本小節我們講解一下pytest fixture測試夾具的使用方法。 前言 在做自動化的過程中&#xff0c;編寫用例時候需要用到用例的前置和用例的后置&a…

2024年了,抖店還能做嗎?適合新手嗎?

我是電商珠珠 現在已經24年了&#xff0c;抖店也已經發展了四年了。其中有很多在門外觀望的人&#xff0c;還在猶豫不決。認為抖店發展到今天&#xff0c;所有的紅利早已在20年的時候就消失殆盡了&#xff0c;特別是沒有經驗的如果入駐了&#xff0c;既不能享受平臺紅利&#…

后端程序員入門react筆記(四)-綜合運用,寫一個小demo

樣式模塊化 有時候我們會遇到這樣的問題&#xff0c;有兩個css對一個class聲明了樣式&#xff0c;這樣的話后引入的css會覆蓋前面的css樣式&#xff0c;導致樣式沖突&#xff0c;那么我們怎么解決這種問題呢&#xff0c;我們可以使用樣式的模塊化&#xff0c;我們起名一個inde…

全棧筆記_瀏覽器擴展篇(插件開發 - chrome瀏覽器proxy代理)

代理類型 常用的包括http、https、socks代理 配置權限 要讓擴展使用代理接口,需要聲明proxy權限: // manifest.json "permissions": ["proxy" ]設置代理服務器 chrome.proxy.settings.set({ scope: ‘regular’, value: 代理配置},回調函數) 代理配…

【前端面經2】京東一面

題目來源&#xff1a;牛客網 自我介紹 動態參數解析的解決方案 對于動態部分使用…args進行接受&#xff0c;可以把動態部分提取成數組 前端安全問題 CDN劫持 內容安全策略CSP 安全沙箱 Iframe 跨站腳本攻擊XSS 攻擊者通過在目標網站上注入惡意腳本&#xff0c;使之在…

OpenHarmony驅動框架HDF中設備管理服務構建過程詳解

前言 如下圖&#xff0c;開源鴻蒙系統驅動框架HDF在內核中的實現&#xff0c;可以分為向用戶層提供設備服務的管理模塊&#xff08;Manager&#xff09;&#xff0c;和實際管理硬件的Host模塊。 Manager分為DeviceManageService和 DeviceServiceManage&#xff0c;前者負責提供…

1.WEB滲透測試-前置基礎知識-ip地址

ip地址&#xff1a; ip地址指的是互聯網協議地址&#xff0c;是IP協議提供的一種統一的地址格式&#xff0c;以每一臺聯網的主機都有一個對應的ip地址&#xff0c;ip地址也可以理解為分配給用戶上網使用的網際協議的設備的數字標簽。通俗的來說就是你打電話時候的每個人都有自己…

AIGC 實戰:如何使用 Docker 在 Ollama 上離線運行大模型(LLM)

Ollama簡介 Ollama 是一個開源平臺&#xff0c;用于管理和運行各種大型語言模型 (LLM)&#xff0c;例如 Llama 2、Mistral 和 Tinyllama。它提供命令行界面 (CLI) 用于安裝、模型管理和交互。您可以使用 Ollama 根據您的需求下載、加載和運行不同的 LLM 模型。 Docker簡介 D…

在Mac上搭建MongoDB環境

最近工作中需要裝MongoDB環境&#xff0c;搭建過程中遇到了一些問題&#xff0c;在這里記錄一下安裝MongoDB環境的方法以及問題的解決方法。有兩種安裝MongoDB的方法&#xff1a;brew安裝和手動安裝。 目錄 使用Homebrew安裝MongoDB 手動安裝MongoDB&#xff08;不使用Homebr…

備戰藍橋杯 Day11(滾動數組優化+完全背包)

01背包的滾動數組優化 【題目描述】 經典0—1背包問題,有n個物品&#xff0c;編號為i的物品的重量為w[i]&#xff0c;價值為c[i]&#xff0c;現在要從這些物品中選一些物品裝到一個容量為m的背包中&#xff0c;使得背包內物體在總重量不超過m的前提下價值盡量大。 #include&…

python_數據分析_numpy庫

一、創建ndarray *ndarray是NumPy中表示數組的重要類型 1、使用np.array()創建 *參數列表&#xff1a;[1,2,3,4] 注&#xff1a;(1)、numpy默認ndarray的所有元素的類型是相同的 ? (2)、如果傳入的數據類型不同&#xff0c;會被按照優先級強制轉換為同一類型&#xff0c;其…

vue--兩種定時任務cron表達式組件比較選擇

背景&#xff1a; 使用vue頁面中cron表達式的組件&#xff0c;實現定時任務參數配置。 方案1 vue-cron 安裝插件 npm install vue-cron --save 全局引入&#xff0c;修改main.js import Vue from vue import VueCron from vue-cron Vue.use(VueCron);頁面配置 html<el-…

Java入門-可重入鎖

可重入鎖 什么是可重入鎖? 當線程獲取某個鎖后&#xff0c;還可以繼續獲取它&#xff0c;可以遞歸調用&#xff0c;而不會發生死鎖&#xff1b; 可重入鎖案例 程序可重入加鎖 A.class,沒有發生死鎖。 sychronized鎖 package com.wnhz.lock.reentrant;public class Sychroniz…

多普勒變化率的應用 與 FPGA

1.多普勒變化率是一個描述波源和觀察者相對速度變化的物理量&#xff0c;它與加速度有關。 多普勒效應是指當波源和觀察者之間存在相對運動時&#xff0c;觀察者接收到的波頻率與波源發射的頻率之間的差異。這種現象在聲波、電磁波等多種波動中都會出現。多普勒變化率通常用來…