多线程实现并发

news/2024/10/5 3:29:16

多线程并发服务器

架构

void* thread_fun(void* arg)
{while(1){recv()/send()}		
}scokfd = socket()
bind()
listen()
while(1){accept()//连上就创建线程pthread_create(, ,thread_fun, )pthread_detach()
}

案例

/*
#    Multi-process concurrent server
#    https://www.cnblogs.com/kencszqh
#
#    File Name:  多线程并发.c
#    Created  :  2024/6/11
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <sys/signalfd.h>
#include <sys/syscall.h>
#include <sys/prctl.h>
#include <sys/uio.h>#define N 128
#define ERR_LOG(errmsg)                                     \do                                                      \{                                                       \perror(errmsg);                                     \exit(1);                                            \} while (0)typedef struct
{struct sockaddr_in addr;int acceptfd;
} MSG;void *pthread_func(void *arg)
{char buf[N] = {0};ssize_t bytes;MSG *msg = (MSG *)arg;while (1){if ((bytes = read(msg->acceptfd, buf, sizeof(buf))) == -1){if (errno == EINTR){continue;}ERR_LOG("read");}else if (bytes == 0){printf("client quit!\n");pthread_exit(NULL);}if (strncmp(buf, "quit", 4) == 0){printf("client quit!\n");pthread_exit(NULL);}printf("[%s - %d]: %s\n", inet_ntoa(msg->addr.sin_addr), ntohs(msg->addr.sin_port), buf);strcat(buf, " ^_^ ");if (send(msg->acceptfd, buf, strlen(buf), 0) == -1){ERR_LOG("fail to send");}}
}int main(int argc, char *argv[])
{if (argc != 3){fprintf(stderr, "Usage:%s [ip] [port]\n", argv[0]);exit(1);}int sockfd, acceptfd;struct sockaddr_in serveraddr, clientaddr;socklen_t addrlen = sizeof(serveraddr);// 1.创建套接字if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ERR_LOG("socket");}// 2.绑定serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));serveraddr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0){ERR_LOG("bind");}// 3.监听if (listen(sockfd, 5) < 0){ERR_LOG("listen");}// 4.接受客户端连接while (1){if ((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0){ERR_LOG("accept");}MSG msg;msg.addr = clientaddr;msg.acceptfd = acceptfd;pthread_t thread;if (pthread_create(&thread, NULL, pthread_func, (void *)&msg) != 0){ERR_LOG("pthread_create");}pthread_detach(thread);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/44248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

IO多路复用

高性能并发IO多路复用详解IO多路复用什么是IO多用复路 IO多路复用(Input/Output Multiplexing)是一种在单个线程中管理多个输入/输出通道的技术。它允许一个线程同时监听多个输入流(例如网络套接字、文件描述符等),并在有数据可读或可写时进行相应的处理,而不需要为每个通…

利用聚合API平台的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端

目录题目分析代码结果 题目利用聚合API平台的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端 分析1.需从源代码网站GitHub或SourceForge代码网站下载cJSON库及阅读下载的README相关手册如何使用cJSON库…

[DP] [倍增优化] Luogu P1081 [NOIP2012 提高组] 开车旅行

[NOIP2012 提高组] 开车旅行 题目描述 小 \(\text{A}\) 和小 \(\text{B}\) 决定利用假期外出旅行,他们将想去的城市从 $1 $ 到 \(n\) 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 \(i\) 的海拔高度为\(h_i\),城市 \(i\) 和城市 \…

【esp32 学习笔记】让SD卡发光发热~

原理图:图 SD卡部分图 MCU中与SD卡相关的接口 连接关系如下:[ESP32 IO26 – CS MICROSD] [ESP32 IO23 – MOSI(DI) MICROSD] [ESP32 IO19 – MISO(DO) MICROSD] [ESP32 IO18 – SCK MICROSD] [ESP32 GND – GND MICROSD] [3.3V – VCC MICROSD] 软件: 我们将使用SD卡库…

网络编程练习题---利用cJSON库对服务器返回的JSON格式数据完成解析

利用HTTP协议向聚合数据API发送请求,并利用cJSON库对服务器返回的JSON格式数据完成解析目录题目注意事项实现代码结果展示相关接口指引 题目利用某些平台(聚合API、百度AI、科大讯飞API)的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务…

嵌入式Linux中的LED驱动控制(续)

前面的实例实现了在野火STM32MP157开发板上对三个LED灯的控制,这里来讨论一下该驱动程序的具体实现方式。由于实例使用的是STM32MP157这款芯片,所以先来看一下与该芯片端口操作相关的寄存器。 先看端口模式寄存器MODER,该类型的寄存器在STM32MP157中有11个,即x的值从A到K。…

通讯协议转换Modbus转Profinet网关

Modbus转Profinet网关是工业通信转换设备,能够实现Modbus协议与Profinet协议之间的有效转换和稳定传输。通过该网关,工业设备之间可以实现数据交换和通信,提高生产效率和智能化程度。支持Modbus RTU主从站。此外,Modbus转 Profinet网关自带网络和串口,支持485/232接口Modb…

python栈帧沙箱逃逸

python栈帧沙箱逃逸 一、生成器 生成器(Generator)是 Python 中一种特殊的迭代器,它可以通过简单的函数和表达式来创建。生成器的主要特点是能够逐个产生值,并且在每次生成值后保留当前的状态,以便下次调用时可以继续生成值。这使得生成器非常适合处理大型数据集或需要延迟…