多线程解决socket并发问题

概念

  • 这篇博客我们利用多线程解决服务器并发问题
  • 进程是资源分配最小的单位,线程是CPU调度的最小单位
  • 多进程与多线程比较(下图取自网络,原作者不详)





对比维度

多进程

多线程

总结

数据共享、同步

数据共享复杂,需要用IPC;数据是分开的,同步简单

因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂

各有优势

内存、CPU

占用内存多,切换复杂,CPU利用率低

占用内存少,切换简单,CPU利用率高

线程占优

创建销毁、切换

创建销毁、切换复杂,速度慢

创建销毁、切换简单,速度很快

线程占优

编程、调试

编程简单,调试简单

编程复杂,调试复杂

进程占优

可靠性

进程间不会互相影响

一个线程挂掉将导致整个进程挂掉

进程占优

分布式

适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单

适应于多核分布式

进程占优

代码实现


  • 服务器端利用多线程编程
  • 注意编译的时候加上-lpthread ,否则会出现如下编译错误

undefined reference to `pthread_create’
collect2: ld 返回 1
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void *thread_worker(void *arg);
int *p;
int main(int argc, char **argv)
{
    int                     socket_fd,  connect_fd = -1;
    struct sockaddr_in      serv_addr;             
     pthread_t tid;
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0 )
    {
        printf("create socket failure: %s\n", strerror(errno));
        return -1;
    }
    printf("socket create fd[%d]\n", socket_fd);

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;        
    serv_addr.sin_port = htons(9998);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if( bind(socket_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 )
    {
        printf("create socket failure: %s\n", strerror(errno));
        return -2;
    }
    printf("socket bind ok\n", socket_fd);

    listen(socket_fd, 13); 
    printf("listen fd ok\n", socket_fd);

    while(1)   
    {
        printf("waiting for client's connection......\n", socket_fd);
        connect_fd = accept(socket_fd, NULL, NULL);
        p=&connect_fd;
        if(connect_fd < 0)
        {
            printf("accept new socket failure: %s\n", strerror(errno));
            return -2;
        }
        printf("accept ok, return connect_fd: [%d]\n", connect_fd);
        pthread_create (&tid, NULL,thread_worker, (void *)p);
    } 
    close(socket_fd);
}


void *thread_worker(void *arg)
{
    char                    buf[1024]; 
    int                     cli_fd =*p; 

    memset(buf, 0, sizeof(buf));        
   while(1){
    read(cli_fd, buf, sizeof(buf));     
    printf("read '%s' from client\n", buf);
    printf("send data to client:");
    fgets(buf,sizeof(buf),stdin);
    write(cli_fd, buf, strlen(buf));
    sleep(1);
    }
    close(cli_fd); 

    return NULL;
}


猜你喜欢

转载自blog.csdn.net/XN6666/article/details/80311628