C++多线程服务器,在子线程ctrl+c后,主线程也退出了,return和exit

158 阅读2分钟

项目场景:

  多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建。


问题描述

盲目模仿多进程服务器的写法,归根结底还是自己没有掌握多进程和多线程的区别

模仿多进程服务器,写了多线程服务器。通过测试,多线程完成了多个socket连接并传输数据的任务

int main(int argc,char *argv[]){
    int lfd,cfd;
    int i=0;
    int ret;
    char buf[BUFSIZ];
    pthread_t tid;
    struct sockaddr_in srv_addr,clt_addr;
    socklen_t clt_addr_len;
    struct s_info s_info_array[256];
    //memset(&saddr,0,sizeof(saddr));
    bzero(&srv_addr,sizeof(srv_addr));
    srv_addr.sin_family=AF_INET;
    srv_addr.sin_port= htons(PORT);
    srv_addr.sin_addr.s_addr= htonl(INADDR_ANY);
    lfd= Socket(AF_INET,SOCK_STREAM,0);

    Bind(lfd,(struct sockaddr *)&srv_addr, sizeof(srv_addr));
    Listen(lfd,128);
    while(1){
        clt_addr_len = sizeof(clt_addr_len);
        cfd= Accept(lfd,(struct sockaddr*)&clt_addr,&clt_addr_len);
        
        s_info_array[i].cliaddr = clt_addr;
        s_info_array[i].connfd = cfd;


        ret= pthread_create(&tid,NULL,do_work,(void *)&s_info_array[i]);
        if(ret==-1){
            sys_err("pthread_create error");
        }
        pthread_detach(tid);
        i++;

    }
    return 0;
}

服务端与2个客户端建立连接并接收数据:

image.png 客户端1:

image.png 客户端2:

image.png


原因分析:

子线程的exit退出,把主线程也给退出了:

image.png

exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统;而return 是退出当前函数,返回函数值,把控制权交给调用函数。

exit和return的区别blog.csdn.net/firefly_200…


解决方案:

  • return:使用return返回到上一级。

image.png

  • break:使用break跳出当前循环。

image.png

进程与线程的比较:

1、进程:子进程是父进程的复制品,是获得父进程数据空间、堆和栈的复制品;而线程,相对与进程而言,线程是一个更加接近执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。两者都可以提高程序的并发度,提高程序运行效率和响应时间。

2、线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器(简单来讲就是平时所说的双CPU系统,是对称多处理机中最常见的一种)上运行,而进程则可以跨机器迁移。

3、根本区别就一点:用多进程每个进程有自己的地址空间(address space),线程则共享地址空间。所有其它区别都是由此而来的:a、速度:线程产生的速度快,线程间的通讯快、切换快等,因为他们在同一个地址空间内;b、资源利用率:线程的资源利用率比较好也是因为他们在同一个地址空间内;c、同步问题:线程使用公共变量/内存时需要使用同步机制还是因为他们在同一个地址空间内。

推荐阅读 TCP并发服务器---多进程和多线程