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
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,页面置换算法FIFO(First-In-First-Out)是一种简单的页面置换算法,它按照页面进入内存的顺序来进行页面淘汰。具体实现时,将页面放入一个先进先出的队列中,当需要淘汰页面时,选择队列里面最先进入的页面进行淘汰。 下面是一个简单的FIFO算法命中率实验代码示例: ```python # 定义一个FIFO算法类 class FIFO: def __init__(self, frame_num): self.frame_num = frame_num # 物理内存帧数 self.frame_list = [] # 物理内存帧列表,初始为空 self.page_fault_count = 0 # 缺页中断次数 # 判断页面是否在物理内存中 def page_in_frame(self, page): return page in self.frame_list # FIFO页面置换算法 def replace_page(self, page): # 如果物理内存未满,直接将页面加入物理内存帧列表 if len(self.frame_list) < self.frame_num: self.frame_list.append(page) # 如果物理内存已满,选择最先进入物理内存的页面进行替换 else: self.frame_list.pop(0) # 弹出最先进入物理内存的页面 self.frame_list.append(page) # 将新页面加入物理内存帧列表 self.page_fault_count += 1 # 缺页中断次数加一 # 模拟页面引用过程 def simulate(self, page_list): for page in page_list: if not self.page_in_frame(page): self.replace_page(page) hit_rate = 1 - self.page_fault_count / len(page_list) # 计算命中率 return hit_rate ``` 上面的代码中,我们定义了一个FIFO算法的类`FIFO`,其中`__init__()`方法初始化了物理内存帧数、物理内存帧列表和缺页中断次数。`page_in_frame()`方法用于判断页面是否在物理内存中,`replace_page()`方法实现了FIFO页面置换算法,`simulate()`方法模拟了页面引用过程,并计算了命中率。 我们可以使用如下代码对该FIFO算法进行测试: ```python if __name__ == '__main__': page_list = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] # 页面引用序列 frame_num = 3 # 物理内存帧数 fifo = FIFO(frame_num) # 初始化FIFO算法实例 hit_rate = fifo.simulate(page_list) # 模拟页面引用过程并计算命中率 print("FIFO算法命中率为:{:.2f}%".format(hit_rate*100)) ``` 输出结果为: ``` FIFO算法命中率为:66.67% ``` 可以看出,该FIFO算法在该页面引用序列下的命中率为66.67%。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值