国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

liunx 多進程不阻塞I/O

2019-11-08 18:25:37
字體:
來源:轉載
供稿:網友

思路

??多進程的特性是復制父進程的所有數據,這和多線程的公用內存不一樣,多進程的好處在于不容易出現一些麻煩的內存問題,多線程的互斥是一件很麻煩的事情,當然也因為這樣,多進程也擁有自己的局限性。

??利用 多進程+阻塞I/O 的方式實現不阻塞I/O,簡單來說就是每accept到一個新的連接,就創建一個子進程,通過那個子進程來單方面通信,子進程里面還是用的最簡單的阻塞I/O,這樣的話就能實現維護多用戶同時連接的問題,當然這樣還是不能實現異步I/O,想要實現異步I/O的話,可以在子進程里面創建一個子線程,主線程加子線程就可以實現異步I/O,我這里只是一個簡單的實現,前后不過花了我十幾分鐘時間,所以沒加多線程的內容。

??子進程復制了父進程的數據,所以可以利用父進程里面的套接字和sockaddr。

代碼實現

我這里是用的標準C寫的,沒有C/C++混寫,寫得比較丑,因為只是一個簡單的demo,所以沒有考慮代碼風格的問題

/********************************************************* * Author			: crazy_mad * Last modified	: 2017-01-16 15:39 * Filename			: main.c * Description		:  *********************************************************/#include <sys/socket.h>#include <sys/types.h>#include <arpa/inet.h>#include <netinet/in.h>#include <errno.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/wait.h>#include <unistd.h>#define BUF_LENGTH 256  	// buf長度int main(int argc, char* argv[]){		int on = 1;	int server_fd = socket(AF_INET, SOCK_STREAM, 0);	// 設置socket模式,這里主要是設置的tcp和重復使用地址	if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {		PRintf("setsockopt error: %s/n", strerror(errno));		exit(1);	}	socklen_t len = sizeof(struct sockaddr_in);	struct sockaddr_in server_addr, client_addr;		// 客戶端、服務端地址信息	server_addr.sin_family = AF_INET;						server_addr.sin_port = htons(8001);	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);	// 綁定地址	if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {		printf("bind error: %s/n", strerror(errno));		exit(1);	}	memset(&client_addr, 0, sizeof(client_addr));	listen(server_fd, 10);	while (1) {		int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &len);		char buf[BUF_LENGTH] = { 0 };		// 創建子進程		pid_t child = fork();		int status;		if (child == -1) {	 		// 創建子進程失敗			perror("fork");			exit(EXIT_FAILURE);		} else if (child == 0) {	// 創建子進程成功			printf("child pid=%d ppid=%d created/n", getpid(), getppid());			int ret;			while (1) {				ret = recv(client_fd, buf, BUF_LENGTH, 0);				if (ret <= 0) {		// socket連接斷開(或其他異常)					break;				}				printf("%s/n", buf);			};			printf("child pid=%d exit!/n", getpid());			close(client_fd);		// 回收客戶端套接字			exit(EXIT_SUCCESS);		} else {					// 子進程成功退出			//printf("parent pid=%d ppid=%d/n", getpid(), getppid());			int w = waitpid(child, &status, WUNTRACED | WCONTINUED);			if (w == -1) {			// 子進程退出異常				perror("waitpid");				exit(EXIT_FAILURE);			} else {				// 子進程正常退出				//printf("child exited/n");			}		}	}	close(server_fd);				// 回收套接字	return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新邵县| 南昌县| 长寿区| 临洮县| 奉节县| 育儿| 视频| 翼城县| 九龙城区| 岚皋县| 苏尼特右旗| 柘荣县| 安图县| 绥德县| 西乌珠穆沁旗| 四会市| 广丰县| 北安市| 台山市| 都兰县| 滕州市| 阳新县| 岱山县| 深州市| 黄平县| 新蔡县| 望都县| 依兰县| 毕节市| 永仁县| 六安市| 崇礼县| 资兴市| 商丘市| 翁牛特旗| 南汇区| 黄梅县| 岚皋县| 铜梁县| 荆门市| 涟源市|