Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38087
  • 博文数量: 10
  • 博客积分: 440
  • 博客等级: 下士
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-11 10:22
文章分类
文章存档

2011年(4)

2008年(6)

我的朋友
最近访客

分类: LINUX

2011-01-18 15:20:09

多进程并发服务器模型程序代码
多进程并发服务器模型程序代码
 

/*****************************************************************************/
/* TCP预先派生子进程服务器程序 */
/*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/resource.h>

#define MAXLINE 256
#define MAXN 16384

static int nchildren;
static pid_t *pids;
static pthread_mutex_t *mptr;

void sig_int( int signo );
int tcp_listen( int nPort, int nMax );
pid_t child_make( int i, int listenfd );
void child_main( int i, int listenfd );
void web_child( int sockfd );
ssize_t readn( int fd, void *vptr, size_t n );
ssize_t writen( int fd, void *vptr, size_t n );
ssize_t readline( int fd, void *vptr, size_t maxlen );
void pr_cpu_time( void );

/*****************************************************************************/
/* */
/*****************************************************************************/
int main( int argc, char *argv[] )
{
    int listenfd, i;
    int nPort, nMax = 5;
    
    if (argc != 3)
    {
        printf( "usage: %s <#port> <#children>\n", argv[0] );
        exit( 1 );
    }

    nPort = atoi( argv[1] );

    listenfd = tcp_listen( nPort, nMax );
    if (listenfd < 0)
    {
        printf( "starting service failed!\n" );
        exit( 1 );
    }
    
    nchildren = atoi( argv[argc-1] );
    pids = calloc( nchildren, sizeof(pid_t) );
    
    for (i=0; i<nchildren; i++)
    {
        pids[i] = child_make( i, listenfd ); /* parent returns */
    }
    
    signal( SIGINT, sig_int );
    for (;;)
    {
        pause(); /* everything done by children */
    }
}

/*****************************************************************************/
/* */
/*****************************************************************************/
pid_t child_make( int i, int listenfd )
{
    pid_t pid;
    
    if ((pid = fork()) > 0)
    {
        return( pid ); /* parent */
    }
    
    child_main( i, listenfd ); /*never returns */
    
    return 0;
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void child_main( int i, int listenfd )
{
    int connfd;

    printf( "child %ld starting\n", (long)getpid() );

    for (;;)
    {
        connfd = accept( listenfd, NULL, NULL );
        web_child( connfd ); /* process the request */
        close( connfd );
    }
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void web_child( int sockfd )
{
    int ntowrite;
    ssize_t nread;
    char line[MAXLINE], result[MAXN];
    
    for(;;)
    {
        if ((nread = read( sockfd, line, MAXLINE)) == 0)
        {
            return;
        }

        ntowrite = atoi( line );
        if ((ntowrite <= 0) || (ntowrite > MAXN))
        {
            printf( "client request for %d bytes", ntowrite );
            return;
        }
        writen( sockfd, result, ntowrite );
    }
}

/*****************************************************************************/
/* */
/*****************************************************************************/
int tcp_listen( int nPort, int nMax )
{
    int sockfd;
    struct sockaddr_in addrin;
    struct sockaddr *paddr = (struct sockaddr *)&addrin;
    
    if ((nPort <= 0) || (nMax <= 0))
    {
        return -1;
    }
    
    memset( &addrin, 0x00, sizeof(addrin) );
    
    addrin.sin_family = AF_INET;
    addrin.sin_addr.s_addr = htonl( INADDR_ANY );
    addrin.sin_port = htons( nPort );
    
    sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    if (sockfd < 0)
    {
        return -2;
    }
    
    if (bind(sockfd, paddr, sizeof(addrin)) != 0)
    {
        close( sockfd );
        return -3;
    }
    
    if (listen(sockfd, nMax) != 0)
    {
        close( sockfd );
        return -4;
    }
    
    return sockfd;
}

/*****************************************************************************/
/* */
/*****************************************************************************/
ssize_t readn( int fd, void *vptr, size_t n )
{
    ssize_t nleft;
    ssize_t nread;
    char *ptr;

    ptr = vptr;
    nleft = n;
    while(nleft > 0)
    {
        if ((nread = read(fd, ptr, nleft)) < 0)
        {
            if (errno == EINTR)
            {
                nread = 0; /* and call read() again */
            }
            else
            {
                return(-1);
            }
        }
        else if (nread == 0)
        {
            break; /* EOF */
        }
        nleft -= nread;
        ptr += nread;
    }
    return(n - nleft); /* return >= 0 */
}

/*****************************************************************************/
/* */
/*****************************************************************************/
ssize_t writen( int fd, void *vptr, size_t n )
{
    ssize_t nleft;
    ssize_t nwritten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while(nleft > 0)
    {
        if ((nwritten = write(fd, ptr, nleft)) <= 0)
        {
            if (errno == EINTR)
            {
                nwritten = 0; /* and call write() again */
            }
            else
            {
                return(-1); /* error */
            }
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return(n);
}

/*****************************************************************************/
/* */
/*****************************************************************************/
ssize_t readline( int fd, void *vptr, size_t maxlen )
{
    ssize_t n, rc;
    char c, *ptr;
    
    ptr = vptr;
    for (n=1; n<maxlen; n++)
    {
again:
        if ((rc = read(fd, &c, 1)) == 1)
        {
            *ptr++ = c;
            if (c == '\n')
            {
                break; /* newline is stored, like fgets() */
            }
            else if (rc == 0)
            {
                if (n == 1)
                {
                    return( 0 ); /* EOF, no data read */
                }
                else
                {
                    break; /* EOF, some data was read */
                }
            }
            else
            {
                if (errno == EINTR)
                {
                    goto again;
                }
                return( -1 ); /* error, errno set by read() */
            }
        }
    }
    *ptr = 0; /* null terminate like fgets() */
    return( n );
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void my_lock_init( void )
{
    int fd;
    pthread_mutexattr_t mattr;
    
    fd = open( "/dev/zero", O_RDWR, 0 );
    
    mptr = mmap( 0, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
    
    close( fd );
    
    pthread_mutexattr_init( &mattr );
    pthread_mutexattr_setpshared( &mattr, PTHREAD_PROCESS_SHARED );
    pthread_mutex_init( mptr, &mattr );
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void my_lock_wait( void )
{
    pthread_mutex_lock( mptr );
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void my_lock_release( void )
{
    pthread_mutex_unlock( mptr );
}

/*****************************************************************************/
/* */
/*****************************************************************************/
void sig_int( int signo )
{
    int i;
    
    /* terminate all children */
    for (i=0; i<nchildren; i++)
    {
        kill( pids[i], SIGTERM );
    }
    while(wait(NULL)>0)
        ;
    if (errno != ECHILD)
    {
        printf( "wait error" );
    }
    pr_cpu_time();
    exit(0);
}

void pr_cpu_time( void )
{
    double user, sys;
    struct rusage myusage, childusage;
    
    if (getrusage(RUSAGE_SELF, &myusage) < 0)
    {
        printf( "getrusage error\n" );
    }
    
    if (getrusage(RUSAGE_CHILDREN, &childusage) < 0)
    {
        printf( "getrusage error\n" );
    }
    
    user = (double)myusage.ru_utime.tv_sec +
        myusage.ru_utime.tv_usec/1000000.0;
    user += (double)childusage.ru_utime.tv_sec +
        childusage.ru_utime.tv_usec/1000000.0;
    
    sys = (double)myusage.ru_stime.tv_sec +
        myusage.ru_stime.tv_usec/1000000.0;
    sys += (double)childusage.ru_stime.tv_sec +
        childusage.ru_stime.tv_usec/1000000.0;
    
    printf( "\nuser time=%g, sys time=%g\n", user, sys );
}

发表于: 2008-12-02 ,修改于: 2008-12-02 21:13,已浏览569次,有评论1条 推荐 投诉
阅读(507) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~