环形缓冲区
模拟出来消费者与生产者的关系,其中需要考虑到多线程并发的问题,所以需要用到锁机制pthread_mutex,条件变量pthread_cond_t,后续还需要用到信号量机制sem_t.
主要函数
核心CODE
int put()
{
...
right_have = min(len, fifo->size - fifo->in);
if (right_have == len) {
memcpy(fifo->buf + fifo->in, buf, right_have);
fifo->in += right_have;
} else {
memcpy(fifo->buf + fifo->in, buf, right_have);
memcpy(fifo->buf, buf + right_have, len - right_have);
fifo->in = len - right_have;
}
fifo_payload += len;
...
}
int get()
{
...
right_have = min(len, fifo->size - fifo->out);
if (right_have == len) {
memcpy(buf, fifo->buf + fifo->out, right_have);
fifo->out += right_have;
} else {
memcpy(buf, fifo->buf + fifo->out, right_have);
memcpy(buf + right_have, fifo->buf, len - right_have);
fifo->out = len - right_have;
}
fifo->payload -= len;
...
}
辅助函数
time
/**
*与时间相关的函数
* gettimeofday()
* struct timeval
* struct timezone
**/
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
static void get_timeout_ts(int time_ms, struct timespec *out_ts)
{
struct timeval now;
struct timespec ts;
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec;
ts.tv_nsec = now.tv_usec * 1000;
ts.tv_sec += time_ms / 1000;
ts.tv_nsec += (time_ms % 1000) * 1000 * 1000;
ts.tv_sec += ts.tv_nsec/(1000 * 1000 * 1000);
ts.tv_nsec = ts.tv_nsec%(1000 * 1000 * 1000);
out_ts->tv_sec = ts.tv_sec;
out_ts->tv_nsec = ts.tv_nsec;
}
lock and cond
/**********put**************/
...
pthread_mutex_lock(&fifo->lock);
while ((fifo->size - fifo->payload) < len) {
if (fifo->put_ms == -1) {
pthread_cond_wait(&(fifo->cond), &(fifo->lock));
} else {
get_timeout_ts(fifo->put_ms, &ts);
if (0 != pthread_cond_timedwait(&(fifo->cond), &(fifo->lock), &ts)) {
pthread_mutex_unlock(&(fifo->lock));
return -1;
}
}
}
...
pthread_mutex_unlock(&(fifo->lock));
pthread_cond_signal(&(fifo->cond));
/*********get***********/
.....
pthread_mutex_lock(&fifo->lock);
while ((fifo->payload < len) ) {
//get_frist_flag = 0;
if(fifo->get_ms == -1){
pthread_cond_wait(&(fifo->cond), &(fifo->lock));
}else{
struct timespec ts;
get_timeout_ts(fifo->get_ms, &ts);
if(0 != pthread_cond_timedwait(&(fifo->cond), &(fifo->lock), &ts))
{
pthread_mutex_unlock(&(fifo->lock));
return -1;
}
}
}
.....
pthread_mutex_unlock(&(fifo->lock));
pthread_cond_signal(&(fifo->cond));
简易关系流程图