Linux网络编程之多线程

简介:

多线程模型

在多线程模型下,注意共享数据的同步,mutex/condition_variable/rw_lock等的使用,local thread storage的使用,另外,可以搭配线程池处理异步计算任务。在C++11中的线程库中已经提供了future相关的工具,合理地使用线程模型减少资源的同时,能获得不错的性能

//thread server
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>


#define MAX_READ_CHUNK 2*1024*1024
#define KEEP_ALIVE 0
void run();

int main(int argc, char *argv[])
{
    run();
    return 0;
}

void error_exit()
{
    perror("error");
    exit(EXIT_FAILURE);
}


int do_read_and_write(int clientfd)
{
    char read[MAX_READ_CHUNK];
    ssize_t result;
    result = recv(clientfd, read, sizeof(read), 0);
    if (result<=0){
        perror("error recv data");
        return -1;
    }

    //write back
    result = send(clientfd, read, result, 0);

    if (result<=0){
        perror("error send data");
        return -1;
    }

    if(!KEEP_ALIVE)
        close(clientfd);
    return 0;
}

void *handle_client_socket(void *clientfd)
{
    if (pthread_detach(pthread_self())!=0){
        error_exit();
    }
    int client = *(int *)clientfd;
    if (clientfd!=NULL){
        free(clientfd);
        clientfd = NULL;
    }
    if (do_read_and_write(client)<0){
        error_exit();
    }
    //we set the thread detach,so no need call pthread_exit
    //pthread_exit(NULL);
}


void run()
{
    struct hostent *h;
    h = gethostbyname("localhost");
    if (!h){
        error_exit();
    }

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr = *(struct in_addr*)h->h_addr;
    sin.sin_port = htons(8000);

    int serverfd = socket(AF_INET, SOCK_STREAM, 0);
    if (serverfd<0){
        error_exit();
    }
    int reuse = 1;
    if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))){
        error_exit();
    }

    socklen_t slen = sizeof(sin);
    if (bind(serverfd, (struct sockaddr *)&sin, slen)<0){
        error_exit();
    }

    if (listen(serverfd, 20)<0){
        error_exit();
    }

    struct sockaddr_in client;
    socklen_t slen_client = sizeof(client);
    int clientfd;
    pthread_t pt;

    while(1){

        clientfd = accept(serverfd, (struct sockaddr *)&client, &slen_client);
        if (clientfd<0){
            error_exit();
        }

        int *temp = (int *) malloc(sizeof(int));
        *temp = clientfd;
        if(pthread_create(&pt, NULL, handle_client_socket, temp)!=0){
            error_exit();
        }

    }

}   
相关文章
|
2月前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
99 2
|
4月前
|
安全 Linux 网络安全
Web安全-Linux网络协议
Web安全-Linux网络协议
85 4
|
12天前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
53 15
|
17天前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
129 7
|
3月前
|
运维 监控 网络协议
|
3月前
|
Java 应用服务中间件
面对海量网络请求,Tomcat线程池如何进行扩展?
【10月更文挑战第4天】本文详细探讨了Tomcat线程池相较于标准Java实用工具包(JUC)线程池的关键改进。首先,Tomcat线程池在启动时即预先创建全部核心线程,以应对启动初期的高并发请求。其次,通过重写阻塞队列的入队逻辑,Tomcat能够在任务数超过当前线程数但未达最大线程数时,及时创建非核心线程,而非等到队列满才行动。此外,Tomcat还引入了在拒绝策略触发后重新尝试入队的机制,以提高吞吐量。这些优化使得Tomcat线程池更适应IO密集型任务,有效提升了性能。
面对海量网络请求,Tomcat线程池如何进行扩展?
|
3月前
|
Ubuntu Linux 虚拟化
Linux虚拟机网络配置
【10月更文挑战第25天】在 Linux 虚拟机中,网络配置是实现虚拟机与外部网络通信的关键步骤。本文介绍了四种常见的网络配置方式:桥接模式、NAT 模式、仅主机模式和自定义网络模式,每种模式都详细说明了其原理和配置步骤。通过这些配置,用户可以根据实际需求选择合适的网络模式,确保虚拟机能够顺利地进行网络通信。
135 1
|
3月前
|
网络协议 安全 Ubuntu
Linux中网络连接问题
【10月更文挑战第3天】
45 1
|
3月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
45 0
Linux C/C++之线程基础
|
3月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
81 2