linux網絡編程之多線程多進程服務器與進程線程池

一.實現tcp服務端多進程編寫

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<string.h>
#include <netinet/in.h>

static void usage(const char* proc)
{
        printf("Usage:%s [local_ip] [local_port]\n",proc);
}

int startup(const char* _ip,int _port)
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0 )
    {
        perror("socket");
        exit(2);
    }
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = inet_addr(_ip);

    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
    {
        perror("bind");
        exit(3);
    }

    if(listen(sock,10) < 0)
    {
        perror("listen");
        exit(4);
    }
    return sock;
}



  //./tcp_server ip port
int main(int argc,char* argv[] )
{
    if(argc!=3)
    {
        usage(argv[0]);
        return 1;
    }

      while(1)
      {
        struct sockaddr_in client;
        socklen_t len = sizeof(client);

        int listen_sock = startup(argv[1],atoi(argv[2]));
        int new_sock = accept(listen_sock,(struct sockaddr*)&client,&len);

        if(new_sock<0)
        {
            perror("acc");
            continue;
        }
        printf("get a new client ,%s:%d\n",inet_ntoa(client.sin_addr),
                ntohs(client.sin_port));


        pid_t id = fork();
        if(id<0)
        {
            close(new_sock);
        }
        else if(id==0)//child
        {
            close(listen_sock);
            if(fork()>0)
            {
                exit(0);
            }
            while(1)
            {

                char buf[1024];
                ssize_t s= read(new_sock,buf,sizeof(buf)-1);
                if(s>0)
                {
                    buf[s]=0;
                    printf("client: %s\n",buf);
                    printf("client: %s\n",buf);
                    write(new_sock,buf,strlen(buf));
                }
                else if(s==0)
                {   
                    close(new_sock);
                    printf("client is quit\n");
                    break;
                }

                else
                {

                    perror("read");
                    exit(5);        

                }
            }
        }
        else 
        {
            close(new_sock);
        }
      }
}

二.實現tcp服務端多線程編寫

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<string.h>
#include <netinet/in.h>
#include<pthread.h>


static void usage(const char* proc)
{
        printf("Usage:%s [local_ip] [local_port]\n",proc);
}

int startup(const char* _ip,int _port)
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0 )
    {
        perror("socket");
        exit(2);
    }
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = inet_addr(_ip);

    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
    {
        perror("bind");
        exit(3);
    }

    if(listen(sock,10) < 0)
    {
        perror("listen");
        exit(4);
    }
    return sock;
}

void* handlerRequest(void* arg)
{
    int new_sock = (int)arg;
    while(1)
    {
        char buf[10240];
        size_t s=read(new_sock,buf,sizeof(buf)-1);
        if(s>0)
        {
            buf[s] =0;
            printf("client:%s\n",buf);
            write(new_sock,buf,strlen(buf));
        }
        else if(s==0)
        {
            close(new_sock);
            printf("client quit\n");
            break;
        }
        else
        {
            perror("read");
            close(new_sock);
            break;
        }
    }
}

  //./tcp_server ip port
int main(int argc,char* argv[] )
{
    if(argc!=3)
    {
        usage(argv[0]);
        return 1;
    }

    int listen_sock = startup(argv[1],atoi(argv[2]));
    while(1)
    {
        struct sockaddr_in client;
        socklen_t len = sizeof(client);

        int new_sock = accept(listen_sock,\
                (struct sockaddr*)&client,&len);
        if(new_sock<0)
        {
            perror("accept");
            continue;
        }

        printf("get a new client ,%s:%d\n",\
                inet_ntoa(client.sin_addr),\
                ntohs(client.sin_port));

        pthread_t id;
        pthread_create(&id,NULL,handlerRequest,(void*)new_sock);
        pthread_detach(id);
    }

}

三.進程池

進程池技術的應用至少由以下兩部分組成:

  • 資源進程
    預先創建好的空閒進程,管理進程會把工作分發到空閒進程來處理。

  • 管理進程
    管理進程負責創建資源進程,把工作交給空閒資源進程處理,回收已經處理完工作的資源進程。
    上面資源進程跟管理進程的概念很好理解,下面就是進程池的關鍵,管理進程如何有效的管理資源進程,分配任務給資源進程,回收空閒資源進程,管理進程要有效的管理資源進程,那麼管理進程跟資源進程間必然需要交互,通過IPC,信號,信號量,消息隊列,管道等進行交互。

四.線程池

線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然後在創建線程後自動啓動這些任務。線程池線程都是後臺線程。每個線程都使用默認的堆棧大小,以默認的優先級運行,並處於多線程單元中。如果某個線程在託管代碼中空閒(如正在等待某個事件),則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間後創建另一個輔助線程但線程的數目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成後才啓動。

作用:

應用程序可以有多個線程,這些線程在休眠狀態中需要耗費大量時間來等待事件發生。其他線程可能進入睡眠狀態,並且僅定期被喚醒以輪循更改或更新狀態信息,然後再次進入休眠狀態。爲了簡化對這些線程的管理,.NET框架爲每個進程提供了一個線程池,一個線程池有若干個等待操作狀態,當一個等待操作完成時,線程池中的輔助線程會執行回調函數。線程池中的線程由系統管理,程序員不需要費力於線程管理,可以集中精力處理應用程序任務。

線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然後在創建線程後自動啓動這些任務。線程池線程都是後臺線程.每個線程都使用默認的堆棧大小,以默認的優先級運行,並處於多線程單元中.如果某個線程在託管代碼中空閒(如正在等待某個事件),則線程池將插入另一個輔助線程來使所有處理器保持繁忙.如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間後創建另一個輔助線程但線程的數目永遠不會超過最大值.超過最大值的線程可以排隊,但他們要等到其他線程完成後才啓動

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章