C语言epoll实现线程池

/*************************************************************************
	> File Name: 5.thread_epoll.c
	> Author:
	> Mail:
	> Created Time: Fri 14 Aug 2020 10:59:44 AM CST
 ************************************************************************/

#include<stdio.h>
#include"../../common/head.h"
#include"../../7.thread_pool/thread_pool.h"
#define MAX 10
#define MAXUSER 1024
#define SIZE 50
#define THREADNUM 5
#define BUFFSIZE 512
int full_flag = 0, empty_flag = 0;
char buff[512] = {0};

int main(int argc, char **argv) {
    char buffer[SIZE][BUFFSIZE] = {0};
    if (argc != 2) {
        fprintf(stderr, "Usage : %s port!\n", argv[0]);
        exit(1);
    }
    int server_listen, sockfd, port, epollfd;
    int fd[MAXUSER] = {0};
    port = atoi(argv[1]);
    if ((server_listen = socked_create(port)) < 0) {
        perror("socket_create()");
        exit(1);
    }

    if ((epollfd = epoll_create(1)) < 0) {
        perror("epoll_create()");
        exit(1);
    }
    struct task_queue taskQueue;
    task_queue_init(&taskQueue, SIZE);
    pthread_t tid[THREADNUM];
    for (int i = 0; i < THREADNUM; i++) {
        pthread_create(&tid[i], NULL, thread_run, (void *)&taskQueue);
    }
    struct epoll_event ev, events[MAX];

    ev.data.fd = server_listen;
    ev.events = EPOLLIN;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, server_listen, &ev) < 0) {
        perror("epoll_ctl()");
        exit(1);
    }
    while (1) {
        int nfds = epoll_wait(epollfd, events, MAX, -1);
        if (nfds <= 0) {
            perror("epoll_wait");
            exit(1);
        }
        for (int i = 0; i < nfds; ++i) {
            int sub = 0;
        if (events[i].data.fd == server_listen  && (events[i].events & EPOLLIN)) {
                if ((sockfd = accept(server_listen, NULL, NULL)) < 0) {
                    perror("accept()");
                    exit(1);
                }
                fd[sockfd] = sockfd;
                ev.events = EPOLLIN;
                ev.data.fd = sockfd;
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) < 0) {
                    perror("epoll_ctl()");
                    exit(1);
                }
            }
            else if (events[i].events & EPOLLIN) {
                int p = recv(events[i].data.fd, buffer[sub], sizeof(buffer[sub]), 0);
                task_queue_push(&taskQueue, buffer[sub]);
                if (++sub >= 100) sub = 0;

                if (p <= 0) {
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
                    DBG("events[i].data.fd_1 = %d\n", events[i].data.fd);

                    task_queue_pop(&taskQueue);
                    close(events[i].data.fd);
                    printf("logout_1\n");
                    exit(1);

                }

            }
             /*if(events[i].events & EPOLLRDHUP) {
                epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
                DBG("events[i].data.fd = %d\n", events[i].data.fd);
                close(events[i].data.fd);
                printf("logout\n");
                exit(1);
            }*/
        }
    }

    return 0;
}
void *thread_run(void *arg) {
    pthread_detach(pthread_self());
    struct task_queue *taskQueue = (struct task_queue *)arg;
    while (1) {
        char *str = task_queue_pop(taskQueue);
        printf("<%ld> %s\n", pthread_self(), str);
    }
    for (int i = 0; i < taskQueue->total; i++) {
        free(taskQueue->data[i]);
    }
    free(taskQueue->data);
}

void task_queue_init(struct task_queue *taskQueue, int size) {
    memset(taskQueue, 0, sizeof(struct task_queue));
    taskQueue->data = (char **)calloc(size, sizeof(char *));
    taskQueue->size = size;
    taskQueue->total = taskQueue->tail = taskQueue->head = 0;
    pthread_mutex_init(&taskQueue->mutex, NULL);
    pthread_cond_init(&taskQueue->cond, NULL);
}

void task_queue_push(struct task_queue *taskQueue, char *str) {
    if (taskQueue->total > taskQueue->size) {
        perror("total bound");
        exit(1);
    }

    pthread_mutex_lock(&taskQueue->mutex);
    if (taskQueue->total == taskQueue->size) {
        DBG(YELLOW"<FULL WAIT>\n"NONE BLUE);
        full_flag = 1;
        pthread_cond_wait(&taskQueue->cond, &taskQueue->mutex);
    }

    taskQueue->data[taskQueue->tail] = (char *)calloc(512, sizeof(char));
    strcpy(taskQueue->data[taskQueue->tail++], str);

    DBG(GREEN("PUSH ") ": %s\n", taskQueue->data[taskQueue->tail - 1]);

    taskQueue->total += 1;
    if (taskQueue->tail == taskQueue->size) taskQueue->tail -= taskQueue->size;

    pthread_mutex_unlock(&taskQueue->mutex);

    if (empty_flag == 1) {
        DBG(BLUE"<EMPTY\n>"NONE);
        pthread_cond_signal(&taskQueue->cond);
        empty_flag = 0;
    }
}

char *task_queue_pop(struct task_queue *taskQueue) {
    pthread_mutex_lock(&taskQueue->mutex);
    if (taskQueue->total == 0) {
        DBG(BLUE"<EMPTY WAIT>\n"NONE);
        empty_flag = 1;
        pthread_cond_wait(&taskQueue->cond, &taskQueue->mutex);
    }

    static char tmp[512];
    memset(tmp, 0, sizeof(tmp));
    strcpy(tmp, taskQueue->data[taskQueue->head]);
    taskQueue->head++;
    if (taskQueue->head == taskQueue->size) taskQueue->head -= taskQueue->size;
    taskQueue->total -= 1;
    DBG(RED"<POP>"NONE" : %s\n", taskQueue->data[taskQueue->tail - 1]);

    pthread_mutex_unlock(&taskQueue->mutex);

    if (full_flag == 1) {
        DBG(YELLOW"<FULL SIGNAL>\n"NONE);
        pthread_cond_signal(&taskQueue->cond);
        full_flag = 0;
    }
    return tmp;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值