TCP實現線程池競爭任務

服務端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<pthread.h>#define SERV_PORT 8000
#define MAXLINE 80//打印報錯信息
#define prrexit(msg){ \perror(msg); \exit(1); \}typedef struct Task{int fd;struct Task  *next;
}Task;
//任務池子,隊列
typedef struct Task_pool{Task *head;Task *tail;pthread_mutex_t lock;pthread_cond_t havetask;
}Task_pool;Task_pool *task_pool_init(){Task_pool *tp=(Task_pool *)malloc(sizeof(Task_pool));tp->head=NULL;tp->tail=NULL;pthread_mutex_init(&tp->lock,NULL);pthread_cond_init(&tp->havetask,NULL);return tp;
}void task_pool_push( Task_pool *tp,int fd){pthread_mutex_lock(&tp->lock);Task *t=(Task *)malloc(sizeof(Task));t->fd=fd;t->next=NULL;//兩種情況if(!tp->tail){tp-> head=tp->tail=t;}else{tp->tail->next=t;tp-> tail=t;}pthread_cond_broadcast(&tp->havetask);pthread_mutex_unlock(&tp->lock);
}Task task_pool_pop(Task_pool *tp){pthread_mutex_lock(&tp->lock);//為什么不能用ifwhile(tp->head==NULL){pthread_cond_wait(&tp->havetask,&tp->lock);}Task tmp,*k;k=tp->head;tmp=*k;tp->head=tp->head->next;//隊列一開始為空的情況下if(!tp->head){tp->tail=NULL;}free(k);pthread_mutex_unlock(&tp->lock);return tmp;
}void task_pool_free(Task_pool *tp){pthread_mutex_lock(&tp->lock);Task *p=tp->head,*k;while(p){k=p;p=p->next;free(k);}tp->head=NULL;pthread_mutex_unlock(&tp->lock);pthread_mutex_destroy(&tp->lock);pthread_cond_destroy(&tp->havetask);free(tp);return ;
}//子線程
void *up_server(void *arg){//獲取自己的線程id,自我釋放pthread_detach(pthread_self());//進行安全的類型轉換//  int connfd=(int)(intptr_t)arg;char buff[MAXLINE];int n,i;Task_pool *tp=arg;while(1){ Task tmp=task_pool_pop(tp);int connfd=tmp.fd;printf("get task fd=%d\n",connfd);while(1){n=read(connfd,buff,MAXLINE);if(n<=0){perror("read error  or connections closed");break;}buff[n]='\0';//添加字符串終止符write(1,buff,n);if(strncmp(buff,"quit",4)==0){break;}for(i = 0; i < n ; i++)buff[i]=toupper(buff[i]);write(connfd,buff,n);}printf("finish task fd=%d\n",connfd);close(connfd);}//正常退出return (void *)0;
}int main(){struct sockaddr_in serveraddr,claddr;int listenfd, connfd;socklen_t  claddr_len;// char buff[MAXLINE];char str[INET_ADDRSTRLEN];int n,i;//任務池創建Task_pool *tp=task_pool_init();//多線程   pthread_t  tid;//多少核就多少個//一上來就會打印idfor(i=0;i<4;i++){pthread_create(&tid,NULL,up_server,(void *)(intptr_t)tp);printf("new thread is %#lx\n",tid);}listenfd =socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){prrexit("socket");}//服務器ip地址,端口初始化bzero(&serveraddr,sizeof(serveraddr));serveraddr.sin_family=AF_INET;serveraddr.sin_port = htons(SERV_PORT);serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(listenfd,(struct  sockaddr *)&serveraddr,sizeof(serveraddr))<0)prrexit("bind");if(listen(listenfd,3)<0)prrexit("listen");printf("Accepting connections...\n");while(1){claddr_len= sizeof(claddr);connfd=accept(listenfd,(struct sockaddr *)&claddr,&claddr_len);if(connfd<0)prrexit("accept");printf("received from %s:%d\n",inet_ntop(AF_INET,&claddr.sin_addr,str,sizeof(str)),ntohs(claddr.sin_port));/*多進程pid_t pid= fork();if(pid<0){prrexit("fork");}//父進程 :等待 創建連接if(pid > 0){close(connfd);//回收進程資源while(waitpid(-1,NULL,WNOHANG)>0){ };continue;}close(listenfd);*///多線程//  pthread_t  tid;//  pthread_create(&tid,NULL,up_server,(void *)(intptr_t)connfd);//  printf("new thread is %#lx\n",tid);task_pool_push(tp,connfd);}task_pool_free(tp);return 0;
}

客戶端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
#include<ctype.h>
#include<arpa/inet.h>
#include<stdlib.h>#define SERV_PORT 8000
#define MAXLINE 80int main(){struct  sockaddr_in servaddr;char buff[MAXLINE];int sockfd = socket(AF_INET, SOCK_STREAM,0);if(sockfd < 0){perror("socket");exit(1);}bzero(&servaddr,sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0){perror("cnnect");exit(1);}printf("Connect to server .Type 'quit' to exit.\n");//死循環進行讀入int n;while((n=read(0,buff,MAXLINE))>0){if(n > 0)buff[n-1] = '\0';//邊界檢查,只比較前四個字節if(strncmp(buff,"quit",4)==0){printf("Quitting ..\n");write(sockfd,buff,strlen(buff));break;}ssize_t bytes_written =write(sockfd,buff,strlen(buff));if(bytes_written!=strlen(buff)){perror("write error");break;}//讀取云服務器響應n = read(sockfd,buff,MAXLINE);if(n<=0){if(n==0){printf("Server closed the connection.\n");}else{perror("read error");}break;}buff[n] = '\0';//確保響應字符串正確終止printf("Server  response: %s\n",buff);printf("Enter next message : ");fflush(stdout);//強制刷新輸出緩沖區}  if(n<0){perror("read from stdin error");}close(sockfd);printf("Client exited.\n");return 0;
}

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

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

相關文章

Redis C++ 實現筆記(F篇)

Implementing Redis in C : F Redis C 實現筆記&#xff08;F篇&#xff09; 前言 本章代碼及思路均來自Build Your Own Redis with C/C 本文章只闡述我的理解想法&#xff0c;以及需要注意的地方。 本文章為續<<Implementing Redis in C : E>>所以本文章不再…

finally 與 return的執行順序

一、第一次試驗public static void main(String[] args) throws InterruptedException {System.out.println(aaa(null));}private static StringBuilder aaa(Integer i) throws InterruptedException {StringBuilder sb new StringBuilder();try {i.toString();return sb;} ca…

Git安裝教程

簡介 Git 是目前全球最流行的分布式版本控制系統&#xff08;Distributed Version Control System, DVCS&#xff09;&#xff0c;核心作用是追蹤文件修改歷史、支持多人協同開發&#xff0c;并能高效管理代碼&#xff08;或任何文本類文件&#xff09;的版本迭代。它由 Linux…

Linux安裝RTL8821CE無線網卡驅動

1. 查看網卡芯片$ lspci | grep Net 01:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8821CE 802.11ac PCIe Wireless Network Adapter2. 預備配套sudo apt install -y dkms git3. 下載驅動并安裝git clone https://github.com/tomaspinho/rtl8821ce.git cd r…

vue3存儲/獲取本地或會話存儲,封裝存儲工具,結合pina使用存儲

目錄 一、基本用法&#xff08;原生 API&#xff09; 1. 存儲數據 2. 獲取數據 3. 刪除數據 二、Vue3 中封裝成工具函數&#xff08;推薦&#xff09; 三、以上工具函數在 Vue3 組件中使用 1. 在選項式 API 中使用 2. 在組合式 API&#xff08;setup 語法糖&#xff09;…

【Flink】DataStream API:基本轉換算子、聚合算子

目錄基本轉換算子映射&#xff08;map&#xff09;過濾&#xff08;filter&#xff09;扁平映射聚合算子按鍵分區&#xff08;keyBy&#xff09;簡單聚合&#xff08;sum/min/max/minBy/maxBy&#xff09;規約聚合&#xff08;reduce&#xff09;基本轉換算子 有如下POJO類用來…

從淘寶推薦到微信搜索:查找算法如何支撐億級用戶——動畫可視化

本篇技術博文摘要 &#x1f31f; 本文通過動畫可視化深入解析數據結構中的核心查找算法&#xff0c;從基礎概念到高階應用&#xff0c;全面覆蓋順序查找、折半查找、分塊查找、B樹/B樹及散列查找的核心原理與實現細節。文章以動態演示為核心工具&#xff0c;直觀展現算法執行過…

圖像正向扭曲反向扭曲

在圖像處理領域&#xff0c;正向扭曲&#xff08;Forward Warping&#xff09;和反向扭曲&#xff08;Backward Warping&#xff09;是兩種核心的圖像坐標映射與像素重采樣技術&#xff0c;核心區別在于“像素映射的方向”——是從“原始圖像”到“目標圖像”&#xff0c;還是從…

【C語言】 第三課 函數與棧幀機制詳解

1 函數的基本概念 在C語言中&#xff0c;函數是程序的基本執行單元。一個函數的定義包括返回類型、函數名、參數列表和函數體。例如&#xff1a; int add(int x, int y) { // 函數定義int z x y;return z; }在使用函數前&#xff0c;通常需要聲明&#xff08; declaration&am…

多個大體積PDF文件怎么按數量批量拆分成多個單獨文件

在現代社會中&#xff0c;電子文檔在我們的身邊無所不在&#xff0c;而PDF文件時我們日常接觸非常多的文檔類型之一。PDF由于格式穩定、兼容性好&#xff0c;因此經常被用于各行各業。但是&#xff0c;我們平時在制作或搜集PDF文件時&#xff0c;文件太大&#xff0c;傳輸和分享…

ansible-角色

角色 一、利用角色構造ansible playbook 隨著開發更多的playbook&#xff0c;會發現有很多機會重復利用以前編寫的playbook中的代碼。或許&#xff0c;一個用于為某一應用配置MySQL數據庫的play可以改變用途。通過利用不同的主機名、密碼和用戶來為另一個應用配置MySQL數據庫。…

git命令行打patch

在 Git 里打 patch&#xff08;補丁&#xff09;其實就是把某些提交的改動導出來&#xff0c;生成一個 .patch 文件&#xff0c;方便別人用 git apply 或 git am 打進代碼里。&#x1f539; 常用方式1. 基于提交導出 patch導出最近一次提交&#xff1a;git format-patch -1 HEA…

文華財經多空提示指標公式 變色K線多空明確指標 文華wh6贏順多空買賣提示指標

XX:240C;YY:MA(C,1);A1:POW(XX,2)/360-POW(YY,2)/260;A5:EMA2(EMA2(A1,20),5),LINETHICK2;A6:A5*0.9999,COLORSTICK;A20:EMA2(EMA2(A5,20),5),LINETHICK2;A60:EMA2(EMA2(A20,20),5),LINETHICK2;支撐:HHV(A5,30),COLORRED;天數:BARSSINCE(A5HHV(A5,0));YL:REF(A5,1)2.79-天數*0.…

記錄一個防重Toast

當我們已經對某個按鈕做了防暴力點擊&#xff0c;但是依然在業務上有些復雜交互的情況&#xff0c;需要我們封裝一個防重Toast。針對這類情況&#xff0c;可以直接使用下面的showDebouncedToastdata class ToastInfo(val id: Any? null,val command: MediaCommandDebouncer.M…

在線測評系統---第n天

主要完成了退出登錄前后的代碼的實現&#xff0c;以及題目列表的查詢1.退出登錄前端引入了全局前置守衛&#xff0c;如果cookie里面沒有token則直接跳轉到login頁面&#xff1b;有則直接跳轉到layout頁面&#xff0c;無需重新登錄后端接收到退出登錄&#xff0c;將token置為無效…

機器學習從入門到精通 - 卷積神經網絡(CNN)實戰:圖像識別模型搭建指南

機器學習從入門到精通 - 卷積神經網絡(CNN)實戰&#xff1a;圖像識別模型搭建指南 各位&#xff0c;是不是覺得那些能認出照片里是貓還是狗、是停車標志還是綠燈的AI酷斃了&#xff1f;今天咱們就擼起袖子&#xff0c;親手搭建一個這樣的圖像識別模型&#xff01;別擔心不需要你…

python sqlalchemy模型的建立

SQLAlchemy 是一個功能強大的 Python SQL 工具包和對象關系映射&#xff08;ORM&#xff09;庫&#xff0c;用于管理和操作關系數據庫。它為 Python 開發者提供了一種用 Python 對象來運行和管理 SQL 數據庫的方式。 目錄 SQLAlchemy 的兩個核心組成部分 SQLAlchemy 的主要功…

Rust中使用RocksDB索引進行高效范圍查詢的實踐指南

在當今海量數據處理場景下,高效的范圍查詢能力成為許多系統的關鍵需求。RocksDB作為一款高性能的嵌入式鍵值存儲引擎,其獨特的LSM樹結構和索引設計為范圍查詢提供了底層支持。本文將深入探討如何在Rust中利用RocksDB的特性來實現高效范圍查詢,從鍵的設計原則到迭代器的工程實…

怎么做到這一點:讓 Agent 可以像人類一樣 邊聽邊想、邊說,而不是“等一句話 → 一次性返回”

要實現“邊聽邊想、邊說”&#xff0c;核心是把整條鏈路做成全雙工、分片流式、可中斷的流水線&#xff1a; ASR 連續吐字 →&#xff08;短緩沖&#xff09;→ LLM 連續出 token&#xff08;可搶斷&#xff09;→ TTS 連續合成并播放&#xff08;可打斷/續播&#xff09;。 下…

Ubuntu 22.04 網絡服務安裝配置

Ubuntu 22.04 網絡服務安裝配置 一鍵安裝所有服務 # 更新系統 sudo apt update# 安裝所有服務 sudo apt install -y openssh-server vsftpd telnetd inetutils-inetd ftp telnet# 啟動所有服務 sudo systemctl start ssh vsftpd inetutils-inetd sudo systemctl enable ssh vsf…