• C程序Linux下多线程并发
    时间:2008-12-04   作者:佚名   出处:互联网

    程序说明: 多线程并发,在接收到请求时,将每个请求创建个线程来执行,原线程(即主线程)继续listen.
    在创建多线程时的主要问题是传入线程参数。
     
    NAME
           pthread_create - create a new thread
    SYNOPSIS
           #include <pthread.h>
           int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <pthread.h>
    #include     <malloc.h>
    #include <stdlib.h>
     
    #define BACKLOG 5
    #define MAXDATASIZE 1000
    #define PORT 1234
     
    void process_cli(int,sockaddr_in);
    void* pthread_receive(void* arg);
     
    */ 
    //for mulThread
    //多线程传递参数为结构体类型
    struct ARG 
    {
    int connectfd;
    sockaddr_in client; 
    };
     
    int main(int argc,char *argv[])      //需要一个参数 端口号
    {
        int    listenfd,                        //监听套接字sock
           connectfd;               //accept 收到的 新套接字
        struct sockaddr_in servAddr,       //服务器地址
                    cliAddr;   //客户端地址
        socklen_t adrlen;                   //sockaddr地址长度
        int           servPort;               //服务器监听端口号
        pid_t             pid;                /*进程ID,多进程程序使用*/
        /*struct packagehead *packhead;*/      //数据包头,下面是多线程所要所用到的变量
        ARG      *arg;
        int    rc;
        pthread_t id;
     
        //获得服务器监听的端口号
       if(argc!=2) 
        { 
            printf("Usage:%s portnumber\a\n",argv[0]); 
            return 1; 
        }
        if((servPort=atoi(argv[1]))<0) 
        { 
            printf("Usage:%s portnumber\a\n",argv[0]); 
            return 1; 
        } 
     
        /* 服务器端开始建立socket描述符 */ 
        if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
        { 
            fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); 
            return 1; 
        }
     
        /*设置套接字地址结构体servAddr中的参数,绑定服务器端口号*/
        bzero(&servAddr,sizeof(servAddr));     //将servAddr结构体重置
        servAddr.sin_family=AF_INET;
        servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
        servAddr.sin_port=htons(servPort);
     
        if(bind(listenfd,(struct sockaddr *)&servAddr,sizeof(servAddr))<0)
        {
            printf("Bind error:%s\n\a",strerror(errno)); 
            exit(2);
       }
        /* 监听sockfd描述符 */ 
        if(listen(listenfd,BACKLOG)==-1) 
        { 
            printf("Listen error:%s\n\a",strerror(errno)); 
            exit(3); 
        } 
     
        while(1)
        {
            printf("%s:waiting for data on port TCP %u\n",argv[0],servPort);
            
            adrlen=sizeof(struct sockaddr_in);
            connectfd=accept(listenfd,(struct sockaddr *)&cliAddr,&adrlen);
            if(connectfd<0)
            {
                /*printf("Accept error:%s\n\a",strerror(errno)); 
                close(*new_sd);
                free(new_sd);*/
                perror("accetp() error\n");
                exit(4);
            }
     
            //采用多线程并发3,新线程传递参数变量用指针
            arg=new ARG;
            arg->connectfd=connectfd;
            memcpy((void *)&arg->client,&cliAddr,sizeof(cliAddr));
            
            rc=pthread_create(&id,NULL,pthread_receive,(void *)arg);
            if(rc!=0)
            {
                printf("Create pthread errer:%s\n\a",strerror(errno));
                /*close(*new_sd);
                free(new_sd);*/
                exit(5);
            }
            
        }
        close(listenfd);
    }
     
    void process_cli(int connectfd, sockaddr_in client)
    {
           //....
        close(connectfd);
    }
     
    void* pthread_receive(void* arg)
    {
    ARG *info;
    info=(ARG *)arg;
    process_cli(info->connectfd,info->client);
     
    delete arg;
    pthread_exit(NULL);
    }

    网友留言/评论

    我要留言/评论