/*************************************************************************
> 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;
}
C语言epoll实现线程池
最新推荐文章于 2023-07-24 14:49:39 发布