fifo 详细讲解实例

FIFO

环形缓冲区
模拟出来消费者与生产者的关系,其中需要考虑到多线程并发的问题,所以需要用到锁机制pthread_mutex,条件变量pthread_cond_t,后续还需要用到信号量机制sem_t.

主要函数

  • pthread_create
  • pthread_destory
  • pthread_mutex_init
  • pthread_mutex_lock
  • pthread_mutex_unlock
  • pthread_cond_init
  • pthread_cond_wait
  • phread_cond_timedwait
  • pthread_cond_signal
  • pthread_cond_broadcast
    主要代码

核心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

  • 与时间有关的code
/**
 *与时间相关的函数
 *	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));

简易关系流程图

perduce cycle_fifo consumer put in lock->unlock loop [ fifo ] make sure not the same time get out pthread_cond_signal perduce cycle_fifo consumer

你可能感兴趣的:(C,算法,编程语言,c语言)