免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 14531 | 回复: 21
打印 上一主题 下一主题

c线程池实现^_^! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-11-09 17:59 |只看该作者 |倒序浏览
/* -------------------------------------------------------------------------
* log.h
  * -------------------------------------------------------------------------
*/

#ifndef __LOG_H
#define __LOG_H

#include <stdio.h>
#include <semaphore.h>

#define LOGLINE_MAX 1024

typedef struct {
    int fd;
    sem_t sem;
    int flags;
} log_t;


#define DEBUG 1
#define INFO  2
#define WARN  3
#define ERROR 4
#define FATAL 5

/*
* Logs to the logfile using printf()-like format strings.
*
* log_t - The value you got back from a log_open() call.
* level - can be one of: DEBUG, INFO, WARN, ERROR, FATAL
* fmt   - is a printf()-like format string, followed by the parameters.
*
* Returns 0 on success, or -1 on failure.
*/
int lprintf( log_t *log, unsigned int level, char *fmt, ... );

#define LOG_TRUNC   1<<0
#define LOG_NODATE  1<<1
#define LOG_NOLF    1<<2
#define LOG_NOLVL   1<<3
#define LOG_DEBUG   1<<4
#define LOG_STDERR  1<<5
#define LOG_NOTID   1<<6

/*
* Initializes the logfile to be written to with fprintf().
*
* fname - The name of the logfile to write to
* flags - The bitwise 'or' of zero or more of the following flags:
*          LOG_TRUNC   - Truncates the logfile on opening
*          LOG_NODATE  - Omits the date from each line of the log
*          LOG_NOLF    - Keeps from inserting a trailing '\n' when you don't.
*          LOG_NOLVL   - Keeps from inserting a log level indicator.
*          LOG_STDERR  - Sends log data to stderr as well as to the log.
*                        (this not implemented yet)
*
* Returns NULL on failure, and a valid log_t (value > 0) on success.
*/
log_t *log_open( char *fname, int flags );

/*
* Closes a logfile when it's no longer needed
*
* log  - The log_t corresponding to the log you want to close
*/
void log_close( log_t *log );

#endif


/* -------------------------------------------------------------------------
* log.c - htun logging functions
  * -------------------------------------------------------------------------
*/

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "log.h"


/* Allows printf()-like interface to file descriptors without the
* complications that arise from mixing stdio and low level calls
* FIXME: Needs date and time before logfile entries.
*/
int lprintf( log_t *log, unsigned int level, char *fmt, ... ) {
    int fd;
    int rc;
    va_list ap;
    time_t now;
    char date[50];
    static char line[LOGLINE_MAX];
    static char threadnum[10];
    int cnt;
    static char *levels[6] = { "[(bad)] ",
                               "[debug] ",
                               "[info ] ",
                               "[warn ] ",
                               "[error] ",
                               "[fatal] " };

    if(!log) return -1;

    /* If this is debug info, and we're not logging it, return */
    if( !(log->flags&LOG_DEBUG) && level == DEBUG ) return 0;

    fd=log->fd;

    /* Prepare the date string   日期*/
    if( !(log->flags&LOG_NODATE) ) {
        now=time(NULL);
        strcpy(date,ctime(&now));
        date[strlen(date)-6]=' ';
        date[strlen(date)-5]='\0';
    }

    /*线程号*/
    if( !(log->flags&LOG_NOTID) ) {
        sprintf(threadnum, "(%lu) ", pthread_self());
    }

    cnt = snprintf(line, sizeof(line), "%s%s%s",
                   log->flags&LOG_NODATE ? "" : date,
                   log->flags&LOG_NOLVL  ? "" :
                       (level > FATAL ? levels[0] : levels[level]),
                   log->flags&LOG_NOTID  ? "" : threadnum);

    va_start(ap, fmt);
    vsnprintf(line+cnt, sizeof(line)-cnt, fmt, ap);    /*如果输入的日志过长会自动截取*/
    va_end(ap);

    line[sizeof(line)-1] = '\0';

    if( !(log->flags&LOG_NOLF) ) {
        /*chomp(line);*/
        /*strcpy(line+strlen(line), "\n");*/
    }
        
    sem_wait(&log->sem);         /*用信号实现同步*/
    rc = write(fd, line, strlen(line));
    sem_post(&log->sem);

    if( !rc ) errno = 0;
    return rc;
}

log_t *log_open( char *fname, int flags ) {
    log_t *log = malloc(sizeof(log_t));

    if(!log) {
        fprintf(stderr, "log_open: Unable to malloc()");
        goto log_open_a;
    }
    log->flags=flags;
    if( !strcmp(fname,"-") ) {
        log->fd = 2;
    } else {
        log->fd = open(fname, O_WRONLY|O_CREAT|O_NOCTTY |
                (flags&LOG_TRUNC ? O_TRUNC : O_APPEND) , 0666);
               
    }
    if( log->fd == -1 ) {
        fprintf(stderr, "log_open: Opening logfile %s: %s",
                fname, strerror(errno));
        goto log_open_b;
    }
    if( sem_init(&log->sem, 0, 1) == -1 ) {
        fprintf(stderr, "log_open: Could not initialize log semaphore.");
        goto log_open_c;
    }
    return log;

log_open_c:
    close(log->fd);
log_open_b:
    free(log);
log_open_a:
    return NULL;
}

void log_close( log_t *log ) {
    sem_wait(&log->sem);
    sem_destroy(&log->sem);
    close(log->fd);
    free(log);
    return;
}

[ 本帖最后由 jyh20031984 于 2006-11-9 18:12 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-11-09 18:00 |只看该作者

go on

/* -------------------------------------------------------------------------
* common.h
* -------------------------------------------------------------------------
*/

#ifndef __COMMON_H
#define __COMMON_H

#include <netinet/in.h>
#include <time.h>

#include "log.h"

#ifdef _DEBUG
#define dprintf lprintf
#else
#define dprintf(...)
#endif



/* Become a daemon: fork, die, setsid, fork, die, disconnect */
void daemonize( void );

/* Check the validity of the configuration data */
/*int config_check( config_data_t *c );
*/
/* Drop privileges to nobody. Optional reason for log */
void dropprivs(char *reason);

/* Get root privileges back. Optional reason for log */
void getprivs(char *reason);

/* initialize signames[] array */
/*void init_signames(void);
*/
/* Variables used by other modules */
extern log_t *log;
/*extern config_data_t *config;*/
/*extern char *signames[64]; *//* 64 names of signals */

#endif /* _COMMON_DEFS_H_ */

/* -------------------------------------------------------------------------
* common.c
* -------------------------------------------------------------------------
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <string.h>
/*#include <sys/socket.h>*/
#include <sys/types.h>
#include <sys/stat.h>
/*#include <netinet/in.h>*/
#include <arpa/inet.h>
#include <pwd.h>


#include "log.h"
#include "common.h"


char *signames[64];


/* Become a daemon: fork, die, setsid, fork, die, disconnect */
void daemonize( void ) {
   pid_t pid ;

   fprintf( stderr, "HTun daemon backgrounding.\n" );
   pid = fork();
   if( pid < 0 ) lprintf( log, ERROR, "Unable to fork()!" );
   if( pid > 0 ) _exit(0) ;   /* parent exits */

   setsid();

   pid = fork() ;
   if( pid < 0 ) lprintf( log, ERROR, "Unable to fork()!" );
   if( pid > 0 ) _exit(0);   /* parent exits */

   chdir("~");
   freopen("/dev/null","r",stdin);
   freopen("/dev/null","w",stdout);
   freopen("/dev/null","w",stderr);
  
}

void dropprivs(char *str) {
    struct passwd *nonpriv = getpwnam("nobody");

    if( !nonpriv ) return;

    setreuid(-1,nonpriv->pw_uid);
    setregid(-1,nonpriv->pw_gid);
    if( str && *str )
        lprintf( log, INFO, "Dropped privs to 'nobody' (%s)", str );
    return;
}

void getprivs(char *str) {
    int rc = setreuid(0,0) | setregid(0,0);
    if( rc == -1 ) {
        lprintf( log, ERROR, "Unable to gain superuser privileges: %s",
                strerror(errno) );
    } else {
        if( str && *str )
            lprintf( log, INFO, "Got superuser privleges (%s)", str );
    }
    return;
}
/*
void init_signames(void) {
    signames[SIGHUP] = "SIGHUP";
    signames[SIGINT] = "SIGINT";
    signames[SIGQUIT] = "SIGQUIT";
    signames[SIGILL] = "SIGILL";
    signames[SIGTRAP] = "SIGTRAP";
    signames[SIGABRT] = "SIGABRT";
    signames[SIGIOT] = "SIGIOT";
    signames[SIGBUS] = "SIGBUS";
    signames[SIGFPE] = "SIGFPE";
    signames[SIGKILL] = "SIGKILL";
    signames[SIGUSR1] = "SIGUSR1";
    signames[SIGSEGV] = "SIGSEGV";
    signames[SIGUSR2] = "SIGUSR2";
    signames[SIGPIPE] = "SIGPIPE";
    signames[SIGALRM] = "SIGALRM";
    signames[SIGTERM] = "SIGTERM";
    signames[SIGSTKFLT] = "SIGSTKFLT";
    signames[SIGCLD] = "SIGCLD";
    signames[SIGCHLD] = "SIGCHLD";
    signames[SIGCONT] = "SIGCONT";
    signames[SIGSTOP] = "SIGSTOP";
    signames[SIGTSTP] = "SIGTSTP";
    signames[SIGTTIN] = "SIGTTIN";
    signames[SIGTTOU] = "SIGTTOU";
    signames[SIGURG] = "SIGURG";
    signames[SIGXCPU] = "SIGXCPU";
    signames[SIGXFSZ] = "SIGXFSZ";
    signames[SIGVTALRM] = "SIGVTALRM";
    signames[SIGPROF] = "SIGPROF";
    signames[SIGWINCH] = "SIGWINCH";
    signames[SIGPOLL] = "SIGPOLL";
    signames[SIGIO] = "SIGIO";
    signames[SIGPWR] = "SIGPWR";
    signames[SIGSYS] = "SIGSYS";
    signames[SIGUNUSED] = "SIGUNUSED";

    return;
}

*/

论坛徽章:
0
3 [报告]
发表于 2006-11-09 18:03 |只看该作者

util

/* -------------------------------------------------------------------------
* util.h
* -------------------------------------------------------------------------
*/

#ifndef __UTIL_H
#define __UTIL_H

#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#include <ctype.h>

/*#undef __EI
#define __EI extern __inline__
*/
/*
* Provides a strncasecmp for non-BSD C libraries
*/
inline int xstrncasecmp( const char *s1, const char *s2, int n );

/*__EI*/
int xstrcasecmp( const char *s1, const char *s2 ) {
    return xstrncasecmp( s1, s2, 0 );
}

/*
* fprintf()-like function but uses a file descriptor or socket descriptor
* instead of a FILE*.
*/
int fdprintf(int fd, char *fmt, ...);

/*
* receives a line of data from fd, and puts up to len bytes into buf.
* Returns NULL if there was no data, or buf on success.
*/
char *recvline( char *buf, int len, int fd );

/*
* Ensures there is no extra data waiting to be received on fd.  If there is,
* it is discarded, and the number of discarded bytes is returned.
*/
int recvflush( int fd );

/*
* Reads exactly len bytes from fd and returns the data in a dynamically
* allocated buffer
*/
char *readloop( int fd, size_t len );

/*
* Takes in a char * and returns a dynamically allocated array of pointers to
* the start of each line. The pointer after the last is set to NULL to
* indicate that there are no more pointers after it. Every occurance of '\n'
* in the input string is CHANGED to '\0' to ease the reading of the strings.
*/
char **splitlines( char *buf );

/*
* Removes any trailing whitespace from str by moving up the null pointer.
*/
__EI
char *chomp( char *str ){
    int i=strlen(str)-1;
    while( i >= 0 ){
        if( isspace((int)str[i]) ) str[i--]='\0'; else break;
    }
    return str;
}

/*
* Pass in a hostname, a pointer to a user supplied hostent struct, a
* sufficiently-sized buffer for user by gethostbyname_r(), and the length of
* the buffer, and resolve() fills in the hostent struct for you, returning a
* pointer to it on success, or NULL on failure.
*/
struct hostent *
resolve( const char *name, struct hostent *hostbuf, char *buf, size_t len );

#endif

/* -------------------------------------------------------------------------
* util.c
* -------------------------------------------------------------------------
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

/*#undef __EI*/
#include "util.h"
#include "log.h"
#include "common.h"

inline int xstrncasecmp( const char *s1, const char *s2, int n ){
    const char *p1=s1, *p2=s2;
    int ctr=0;

    if( s1 == s2 ) return 0;

    while( *p1 && tolower(*p1) == tolower(*p2) ) {
        if( n ) {
            ctr++;
            if( ctr >= n ) return 0;
        }
        p1++; p2++;
    }
    if( !*p1 && *p2 ) return -1;
    else if( !*p2 && *p1 ) return 1;
    else return tolower(*p1)-tolower(*p2);
}

int fdprintf(int fd, char *fmt, ...) {
    FILE *fp = fdopen(dup(fd), "w");  /*复制文件描述符*/
    int rc;
    va_list ap;

    va_start(ap, fmt);
    rc=vfprintf(fp, fmt, ap);
    fflush(fp);
    fclose(fp);
    va_end(ap);
    return rc;
}


/*从指定的文件描述符中读取一行内容,如果行内容超过传入的缓冲则记录日志错误信息*/
char *recvline( char *buf, int len, int fd ){
    char c=0;
    int ctr=0;

    while( ctr < len-2 ){
        if( c != '\n' && read(fd,&c,1) == 1 ){
            buf[ctr]=c;
            ctr++;
        } else {
            break;
        }
    }
    if( ctr == len-2 ){
        while( c != '\n' && read(fd,&c,1) == 1 ) ctr++;
        lprintf( log, WARN,
                "recvline: line exceeded buffer space by %d bytes.",
                ctr-len);
    }
    buf[ctr]='\0';

    if( *buf == '\0' ) return NULL;
    else return buf;
}

int recvflush( int s ) {
    fd_set fds;
    char c=0;
    int rc, cnt=0;
    struct timeval tv;

    FD_ZERO(&fds);
    FD_SET(s, &fds);
    tv.tv_sec = 0;
    tv.tv_usec = 0;

    while( (rc=select(s+1, &fds, NULL, NULL, &tv)) ) {
        if( rc == -1 ) {
            lprintf(log, WARN, "recvflush: select() failed: %s",
                    strerror(errno));
            break;
        }
        if( (rc=read(s, &c, 1)) < 1 ) {
            if( rc == 0 ) {
                lprintf(log, WARN, "recvflush: connection reset by peer");
            } else {
                lprintf(log, WARN, "recvflush: read() failed: %s",
                        strerror(errno));
            }
            break;
        }
        cnt++;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
    }

    dprintf(log, DEBUG, "recvflush: returning %d.", cnt);
    return cnt;
}

/*
* Reads exactly len bytes from fd and returns the data in a dynamically
* allocated buffer
*/
char *readloop( int fd, size_t len ) {
    size_t cnt=0;
    int rc;
    char *buf = malloc(len+1);

    if(!buf) return NULL;

    dprintf(log, DEBUG, "readloop: attempting to read %d bytes from fd #%d",
            len, fd);
    while( cnt < len ) {
        if( (rc=read(fd,buf+cnt,len-cnt)) <= 0 ) {
            if( rc < 0 ) {
                if( errno == EINTR ) continue;
                lprintf(log, WARN, "Reading from sock fd %d: %s.", fd,
                        strerror(errno));
            } else {
                lprintf(log, WARN,
                        "Reading from sock fd %d: Read %d bytes, expected %d",
                        fd, cnt, len);
            }
            free(buf);
            return NULL;
        }
        dprintf(log, DEBUG, "readloop: read() returned %d.", rc);
        cnt += rc;
    }
    buf[len] = '\0';

    return buf;
}

char **splitlines( char *buf ) {
    int cnt = 1;
    char **tmp, **ret = NULL;
    char *cp;

    if( !buf || !*buf ) return NULL;
    if( (ret=malloc(1 + cnt * sizeof(char**))) == NULL ) return NULL;
    ret[0] = buf;
   
    for( cp=buf; *cp; cp++ ) {
        if( *cp != '\n' ) continue;
        if( (tmp=realloc(ret, (++cnt + 1) * sizeof(char**))) == NULL ) {
            free(ret);
            return NULL;
        }
        ret=tmp;

        *cp = '\0';
        ret[cnt-1] = cp + 1;
    }

    ret[cnt] = NULL;
    return ret;
}

/* Thread-safe resolve */
/*
struct hostent * resolve( const char *name, struct hostent *hostbuf, char *buf, size_t len )
{
    struct hostent *hp;
    int herr, rc=0, i;

    for( i=0; i<3; i++ ){
        rc=gethostbyname_r(name, hostbuf, buf, len,&hp, &herr);
        if( !rc ){
            return hp;
        } else if( herr == TRY_AGAIN ){
            continue;
        } else {
            break;
        }
    }
    errno=rc;
    return NULL;
}

*/

论坛徽章:
0
4 [报告]
发表于 2006-11-09 18:05 |只看该作者

tpool

/* -------------------------------------------------------------------------
* tpool.h - htun thread pool defs
* -------------------------------------------------------------------------
*/

#ifndef _TPOOL_H_
#define _TPOOL_H_

#include  <stdio.h>
#include  <pthread.h>

/*
* a generic thread pool creation routines
*/

typedef struct tpool_work{
  void (*handler_routine)();
  void *arg;
  struct tpool_work *next;                  /*任务链表*/
} tpool_work_t;

typedef struct tpool{
  int num_threads;
  int max_queue_size;

  int do_not_block_when_full;
  pthread_t *threads;
  int cur_queue_size;
  tpool_work_t *queue_head;
  tpool_work_t *queue_tail;
  pthread_mutex_t queue_lock;
  pthread_cond_t queue_not_full;
  pthread_cond_t queue_not_empty;
  pthread_cond_t queue_empty;
  int queue_closed;
  int shutdown;
} tpool_t;

/*
* returns a newly created thread pool   初始化连接池
*/
extern tpool_t *tpool_init(int num_worker_threads,
    int max_queue_size, int do_not_block_when_full);

/*
* returns -1 if work queue is busy
* otherwise places it on queue for processing, returning 0
*
* the routine is a func. ptr to the routine which will handle the
* work, arg is the arguments to that same routine
    routine 为函数指针  用于处理具体业务的函数实现  arg为参数

*/
extern int tpool_add_work(tpool_t *pool, void  (*routine)(), void *arg);

/*
* cleanup and close,
* if finish is set the any working threads will be allowd to finish
*/
extern int tpool_destroy(tpool_t *pool, int finish);

/* private */
/*extern void tpool_thread(tpool_t *pool); */


#endif /* _TPOOL_H_ */

/* -------------------------------------------------------------------------
* tpool.c - htun thread pool functions
* -------------------------------------------------------------------------
*/

#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h> /* strerror() */
#include  <pthread.h>

#include "tpool.h"
#include "log.h"
#include "common.h"

/* the worker thread */
void *tpool_thread(void *tpool);


/*********************************
    线程池初始化
*********************************/
tpool_t *tpool_init(int num_worker_threads,             /*线程池线程个数    最大任务数      是否阻塞任务满的时候 */
        int max_queue_size, int do_not_block_when_full)
{
    int i, rtn;
    tpool_t *pool;


lprintf(log, INFO, "init pool  begin ...\n";
    /* make the thread pool structure */
    if((pool = (struct tpool *)malloc(sizeof(struct tpool))) == NULL)
    {
        lprintf(log, FATAL, "Unable to malloc() thread pool!\n";
        return NULL;
    }

    /* set the desired thread pool values */
    pool->num_threads = num_worker_threads;                      /*工作线程个数*/
    pool->max_queue_size = max_queue_size;                       /*任务链表最大长度*/
    pool->do_not_block_when_full = do_not_block_when_full;       /*任务链表满时是否等待*/

    /* create an array to hold a ptr to the worker threads   生成线程池缓存 */
    if((pool->threads = (pthread_t *)malloc(sizeof(pthread_t)
                    *num_worker_threads)) == NULL)
    {
        lprintf(log, FATAL,"Unable to malloc() thread info array\n";
        return NULL;
    }

    /* initialize the work queue  初始化任务链表 */
    pool->cur_queue_size = 0;
    pool->queue_head = NULL;
    pool->queue_tail = NULL;
    pool->queue_closed = 0;
    pool->shutdown = 0;

    /* create the mutexs and cond vars  初始化互斥变量 条件变量 用于线程之间的同步 */
    if((rtn = pthread_mutex_init(&(pool->queue_lock),NULL)) != 0) {
        lprintf(log,FATAL,"pthread_mutex_init %s",strerror(rtn));
        return NULL;
    }
    if((rtn = pthread_cond_init(&(pool->queue_not_empty),NULL)) != 0) {
        lprintf(log,FATAL,"pthread_cond_init %s",strerror(rtn));
        return NULL;
    }
    if((rtn = pthread_cond_init(&(pool->queue_not_full),NULL)) != 0) {
        lprintf(log,FATAL,"pthread_cond_init %s",strerror(rtn));
        return NULL;
    }
    if((rtn = pthread_cond_init(&(pool->queue_empty),NULL)) != 0) {
        lprintf(log,FATAL,"pthread_cond_init %s",strerror(rtn));
        return NULL;
    }

    /*
     * from "man 3c pthread_attr_init"
     * Define the scheduling contention scope for the created thread.  The only
     * value     supported    in    the    LinuxThreads    implementation    is
     * !PTHREAD_SCOPE_SYSTEM!, meaning that the threads contend  for  CPU  time
     * with all processes running on the machine.
     *
     * so no need to explicitly set the SCOPE
     */

    /* create the individual worker threads */
    for(i = 0; i != num_worker_threads; i++)
    {
        if( (rtn=pthread_create(&(pool->threads[i]),NULL,
                        tpool_thread,(void*)pool)) != 0)
        {
            lprintf(log,FATAL,"pthread_create %s\n",strerror(rtn));
            return NULL;
        }

lprintf(log, INFO, "init pthread  %d!\n",i);
        
        
    }
lprintf(log, INFO, "init pool end!\n";
    return pool;
}

int tpool_add_work(tpool_t *pool, void (*routine)(void *), void *arg)
{
    int rtn;
    tpool_work_t *workp;

    if((rtn = pthread_mutex_lock(&pool->queue_lock)) != 0)
    {
        lprintf(log,FATAL,"pthread mutex lock failure\n";
        return -1;
    }

    /* now we have exclusive access to the work queue ! */

    if((pool->cur_queue_size == pool->max_queue_size) &&
            (pool->do_not_block_when_full))
    {
        if((rtn = pthread_mutex_unlock(&pool->queue_lock)) != 0)
        {
            lprintf(log,FATAL,"pthread mutex lock failure\n";
            return -1;
        }
        return -1;
    }

    /* wait for the queue to have an open space for new work, while
     * waiting the queue_lock will be released */
    while((pool->cur_queue_size == pool->max_queue_size) &&
            (!(pool->shutdown || pool->queue_closed)))
    {
        if((rtn = pthread_cond_wait(&(pool->queue_not_full),
                        &(pool->queue_lock)) ) != 0)
        {
            lprintf(log,FATAL,"pthread cond wait failure\n";
            return -1;
        }
    }

    if(pool->shutdown || pool->queue_closed)
    {
        if((rtn = pthread_mutex_unlock(&pool->queue_lock)) != 0)
        {
            lprintf(log,FATAL,"pthread mutex lock failure\n";
            return -1;
        }
        return -1;
    }

    /* allocate the work structure */
    if((workp = (tpool_work_t *)malloc(sizeof(tpool_work_t)))
            == NULL)
    {
        lprintf(log,FATAL,"unable to create work struct\n";
        return -1;
    }

    /* set the function/routine which will handle the work,
     * (note: it must be reenterant) */
    workp->handler_routine = routine;
    workp->arg = arg;
    workp->next = NULL;

    if(pool->cur_queue_size == 0)
    {
        pool->queue_tail = pool->queue_head = workp;
        if((rtn = pthread_cond_broadcast(&(pool->queue_not_empty))) != 0)
        {
            lprintf(log,FATAL,"pthread broadcast error\n";
            return -1;
        }
    }
    else
    {
        pool->queue_tail->next = workp;
        pool->queue_tail = workp;
    }


    pool->cur_queue_size++;

    /* relinquish control of the queue */
    if((rtn = pthread_mutex_unlock(&pool->queue_lock)) != 0)
    {
        lprintf(log,FATAL,"pthread mutex lock failure\n");
        return -1;
    }

    return 0;
}

int tpool_destroy(tpool_t *pool, int finish)
{
    int i, rtn;
    tpool_work_t *cur;   /*当前工作线程句柄*/


lprintf(log, INFO, "destroy pool begin!\n");

    /* relinquish control of the queue */
    if((rtn = pthread_mutex_lock(&(pool->queue_lock))) != 0)
    {
        lprintf(log,FATAL,"pthread mutex lock failure\n");
        return -1;
    }
lprintf(log, INFO, "destroy pool begin 1!\n");
    /* is a shutdown already going on ? */
    if(pool->queue_closed || pool->shutdown)
    {
        if((rtn = pthread_mutex_unlock(&(pool->queue_lock))) != 0)
        {
            lprintf(log,FATAL,"pthread mutex lock failure\n");
            return -1;
        }
        return 0;
    }

lprintf(log, INFO, "destroy pool begin 2!\n");
    /* close the queue to any new work   对于新任务来说所有交易禁止 */
    pool->queue_closed = 1;

    /* if the finish flag is set, drain the queue */
    if(finish)
    {
        while(pool->cur_queue_size != 0)
        {
            /* wait for the queue to become empty,
             * while waiting queue lock will be released */
            if((rtn = pthread_cond_wait(&(pool->queue_empty),
                            &(pool->queue_lock))) != 0)
            {
                lprintf(log,FATAL,"pthread_cond_wait %d\n",rtn);
                return -1;
            }
        }
    }


lprintf(log, INFO, "destroy pool begin 3!\n");
    /* set the shutdown flag */
    pool->shutdown = 1;

    if((rtn = pthread_mutex_unlock(&(pool->queue_lock))) != 0)
    {
        lprintf(log,FATAL,"pthread mutex unlock failure\n");
        return -1;
    }
  /*  return 0; */
  
  lprintf(log, INFO, "destroy pool begin 4!\n");

    /* wake up all workers to rechedk the shutdown flag */
    if((rtn = pthread_cond_broadcast(&(pool->queue_not_empty)))
            != 0)
    {
        lprintf(log,FATAL,"pthread_cond_boradcast %d\n",rtn);
        return -1;
    }
    if((rtn = pthread_cond_broadcast(&(pool->queue_not_full)))
            != 0)
    {
        lprintf(log,FATAL,"pthread_cond_boradcast %d\n",rtn);
        return -1;
    }

    /* wait for workers to exit */
    for(i = 0; i < pool->num_threads; i++)
    {
        if((rtn = pthread_join(pool->threads[i],NULL)) != 0)
        {
            lprintf(log,FATAL,"pthread_join %d\n",rtn);
            return -1;
        }
    }

    /* clean up memory */
    free(pool->threads);
    while(pool->queue_head != NULL)
    {
        cur = pool->queue_head->next;
        pool->queue_head = pool->queue_head->next;
        free(cur);
    }
    free(pool);

lprintf(log, INFO, "destroy pool end!\n");


    return 0;
}


/*****************************************
           线程入口函数
*****************************************/
void *tpool_thread(void *tpool)
{
    tpool_work_t *my_work;
    tpool_t *pool = (struct tpool *)tpool;

   /* int *soket;  */                /*socket 句柄*/

    for(;;) /* go forever */
    {

        pthread_mutex_lock(&(pool->queue_lock));   


        /* sleep until there is work,
         * while asleep the queue_lock is relinquished */
        while((pool->cur_queue_size == 0) && (!pool->shutdown))  /* 任务列表为0  并且 线程池没有关闭 */
        {
            pthread_cond_wait(&(pool->queue_not_empty),          /* 等待直到,任务到来为止 */
                    &(pool->queue_lock));
        }

        /* are we shutting down ?  线程池是否已经关闭,如果线程池关闭则线程自己主动关闭 */
        if(pool->shutdown)
        {
            pthread_mutex_unlock(&(pool->queue_lock));
            pthread_exit(NULL);      /*线程退出状态为空,主线程不捕获各副线程状态*/
        }

        /* process the work */
        my_work = pool->queue_head;  
        pool->cur_queue_size--;
        
        if(pool->cur_queue_size == 0)    /*将任务链表头部去掉,改任务正在处理中*/
            pool->queue_head = pool->queue_tail = NULL;
        else
            pool->queue_head = my_work->next;


        /* broadcast that the queue is not full */
        if((!pool->do_not_block_when_full) &&
                (pool->cur_queue_size == (pool->max_queue_size - 1)))
        {
            pthread_cond_broadcast(&(pool->queue_not_full));
        }

        if(pool->cur_queue_size == 0) /*任务链表为空*/
        {
            pthread_cond_signal(&(pool->queue_empty));
        }

        pthread_mutex_unlock(&(pool->queue_lock));

       /* soket = (int*)my_work->arg;  */
        /* perform the work */
        (*(my_work->handler_routine))(my_work->arg);        /*启动线程业务处理逻辑*/
        free(my_work);
    }
    return(NULL);
}

论坛徽章:
0
5 [报告]
发表于 2006-11-09 18:06 |只看该作者

test

#include <pthread.h>
#include "log.h"
#include "tpool.h"
#include "common.h"


log_t *log;        /*进程全局日志文件句柄,线程内的日志文件句柄可在线程内自行装载,如果交易分日志可根据交易码自行*/


void dowork(void *arg)
{
    char * ptr=(char *)arg;
   
   sleep(1);
   printf("hello world! %s\n",ptr);
   /*  sleep(1); */
   /* lprintf(log,INFO,"hello world %s\n",ptr);*/
}


int main(int argc, char *argv[])
{
    tpool_t *pool;  /*线程池句柄*/
   
   
   /* daemonize(); */
    log=log_open("test.log", 0);
  
    pool=tpool_init(100,200,1);
   
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
   
  
  tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
  
  tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
    tpool_add_work(pool,dowork,"test!");
  
    /*void *tpool_thread(void *tpool);
    */
   
    sleep(10);
    tpool_destroy(pool,1);
  
    log_close(log);
    pthread_exit(NULL);
}

论坛徽章:
0
6 [报告]
发表于 2006-11-09 18:24 |只看该作者
似乎不错! 有时间会慢慢读

论坛徽章:
0
7 [报告]
发表于 2006-11-09 22:58 |只看该作者
楼主,把代码放到附件里啥

论坛徽章:
0
8 [报告]
发表于 2006-11-11 17:16 |只看该作者
原帖由 harly 于 2006-11-9 22:58 发表
楼主,把代码放到附件里啥

同意!!

论坛徽章:
0
9 [报告]
发表于 2006-11-11 19:17 |只看该作者
长啊

论坛徽章:
0
10 [报告]
发表于 2006-11-16 17:04 |只看该作者
好像不全,没有thread的suspend和resume的实现,而且也关联业务多了,
有没suspend thread的线程池实现,通过thread_t完成
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP