生产者与消费者模型:
生产者:生产数据的线程
消费者:使用、处理数据的线程
缓冲区:隔离生产者和消费者,这样可以避免互相等待,提高运行效率。
生产者快于消费者:缓冲区爆满 撑死
消费者快于生产者:缓冲区一直空 饿死
使用条件变量可以解决生产者与消费之间的效率不匹配问题。
生产者快于消费者,通知消费者加速消费,生产者睡眠降低生产速度。
消费者快于生产者,通知生产者加速生产,消费者睡眠降低消费速度。
线程池
由于TCP是面向连接的协议,需要一对一通信,需要为每个客户端进行服务,之前是为每客户端创建一个进程来服务,但创建进程耗费的资源比较大,
而较于进程,线程而适合为每个客户端服务。随着客户端的连接和退出,服务端需要频繁的创建、销毁线程,这比较耗费时间,如何解决?
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。可以避免频繁创建销毁线程。
来看下具体代码实现:
queue_array.h
#ifndef QUEUE_ARRAY_H
#define QUEUE_ARRAY_H
#include <stdio.h>
#include <stdbool.h>
typedef struct QueueArray
{
void** arr;
size_t cal;
int front;
int rear;
}QueueArray;
// 创建队列
QueueArray* create_queue(size_t cal);
// 销毁队列
void destroy_queue(QueueArray* queue);
// 判断队列是否已满
bool full_queue(QueueArray* queue);
// 判断队列是否为空
bool empty_queue(QueueArray* queue);
// 入队
void push_queue(QueueArray* queue,void* ptr);
// 出队
void pop_queue(QueueArray* queue);
// 获取队头元素
void* front_queue(QueueArray* queue);
// 获取队尾元素
void* rear_queue(QueueArray* queue);
// 计算队列的元素数量
size_t size_queue(QueueArray* queue);
#endif//QUEUE_ARRAY_H
queue_array.c
#include <stdlib.h>
#include "queue_array.h"
// 创建队列
QueueArray* create_queue(size_t cal)
{
QueueArray* queue = malloc(sizeof(QueueArray));
queue->arr = malloc(sizeof(void*)*cal+1);
queue->front = 0;
queue->rear = 0;
queue->cal = cal+1;
return queue;
}
// 销毁队列
void destroy_queue(QueueArray* queue)
{
free(queue->arr);
free(queue);
}
// 判断队列是否已满
bool full_queue(QueueArray* queue)
{
return (queue->rear+1)%queue->cal == queue->front;
}
// 判断队列是否为空
bool empty_queue(QueueArray* queue)
{