当前位置: 首页 > news >正文

普宁网站建设在线p图

普宁网站建设,在线p图,成都软件开发外包,当当网网站建设步骤问题说明 通过 std::condition_variable 来实现超时等待,会受到系统时间变化的影响,系统时间倒退修改就会导致延后唤醒,系统时间提前将会导致提前被唤醒,返回结果仍为超时。 这种问题只有在系统时间发生变化的时候才会出现&…

问题说明

通过 std::condition_variable 来实现超时等待,会受到系统时间变化的影响,系统时间倒退修改就会导致延后唤醒,系统时间提前将会导致提前被唤醒,返回结果仍为超时。

这种问题只有在系统时间发生变化的时候才会出现,例如搭配 NTP 更新功能,硬件还未同步时间时,一般在 1993 年,此时使用了 wait_for() 这类接口等待 10 秒,结果在 10 秒内被 ntp 同步更新了时间到 2023,那么时间生效的一瞬间,wait_for() 就会直接被唤醒,且返回的结果是超时唤醒。

另外一种时间倒退的场景,则影响会更大,例如在 2023 年,时间调回了 2022 年,那么 wait_for() 将会等待一年多才会被超时唤醒,代码的表现现象则是该线程出现了 wait() 的效果。

通过分析 std::condition_variable 源码,可以很清晰看到使用的是系统时间:
在这里插入图片描述在这里插入图片描述

示例代码:

实现一个可以随时被打断的延时等待类。

有隐患的代码

bool DelayControl::delay(unsigned int millisecond)
{bool is_timeout	= false;unique_lock< mutex > lock(mutex_data_);is_runing_ = true;is_timeout = (cv_status::timeout == cond_.wait_for(lock, chrono::milliseconds(millisecond)));is_runing_ = false;lock.unlock();return is_timeout;
}
void DelayControl::stop()
{unique_lock< mutex > lock(mutex_data_);cond_.notify_all();
}

改进方案一(使用 select 方式实现):缺点是一个对象会浪费两个文件描述符资源

DelayControl::DelayControl()
{is_runing_ = false;pipe(pipefd_);
}bool DelayControl::delay(unsigned int millisecond)
{int result;fd_set rdfs;struct timeval timeout;bool is_timeout = false;is_runing_ = true;FD_ZERO(&rdfs);FD_SET(pipefd_[0], &rdfs);timeout.tv_sec = millisecond / 1000;timeout.tv_usec = (millisecond - ((millisecond / 1000) * 1000)) * 1000;switch((result = select(pipefd_[1] + 1, &rdfs, NULL, NULL, &timeout))){case 0: is_timeout = true; break;}is_runing_ = false;return is_timeout;
}void DelayControl::stop()
{write(pipefd_[1], "", 1);
}

改进方案二(使用 pthread_cond_timedwait 方式实现):完美方案

关键在于使用了 CLOCK_MONTONIC ,其用不是系统时间,而是内核的计数器 jiffies,系统每次启动时,jiffies初始化为0。每来一个timer interrupt,jiffies加1,即它代表系统启动后流逝的tick数,jiffies 只会单调递增。

DelayControl::DelayControl()
{is_runing_ = false;pthread_condattr_init(&cond_cattr_);pthread_mutex_init(&mutex_data_, NULL);pthread_condattr_setclock(&cond_cattr_, CLOCK_MONOTONIC);pthread_cond_init(&cond_, &cond_cattr_);
}DelayControl::~DelayControl()
{pthread_mutex_lock(&mutex_data_);pthread_cond_broadcast(&cond_);pthread_mutex_unlock(&mutex_data_);pthread_cond_destroy(&cond_);pthread_mutex_destroy(&mutex_data_);
}bool DelayControl::delay(unsigned int millisecond)
{struct timespec tv;bool is_timeout = false;pthread_mutex_lock(&mutex_data_);is_runing_ = true;clock_gettime(CLOCK_MONOTONIC, &tv);millisecond += (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);tv.tv_sec = millisecond / 1000;tv.tv_nsec = (millisecond - ((millisecond / 1000) * 1000)) * 1000 * 1000;is_timeout = pthread_cond_timedwait(&cond_, &mutex_data_, &tv) ? true : false;is_runing_ = false;pthread_mutex_unlock(&mutex_data_);return is_timeout;
}bool DelayControl::isRuning()
{bool is_runing = false;pthread_mutex_lock(&mutex_data_);is_runing = is_runing_;pthread_mutex_unlock(&mutex_data_);	return is_runing;
}void DelayControl::stop()
{pthread_mutex_lock(&mutex_data_);is_runing_ = false;pthread_cond_broadcast(&cond_);pthread_mutex_unlock(&mutex_data_);
}

用如下随机设置系统时间的方式压力测 6 小时通过:

#define RAND(_MIN_, _MAX_) (rand() % (_MAX_-_MIN_+1) + _MIN_)
int main()
{Logger::getInstance().init("/mnt/UDISK/pre_bullying/logs/DelayControl.log", 1024*1024*2, 1);std::shared_ptr<MeasureTime> sp_timer_;std::shared_ptr<DelayControl> sp_delay_;sp_delay_ = std::make_shared<DelayControl>();sp_timer_ = std::make_shared<MeasureTime>(100);srand((unsigned)time(NULL)); {DelayControl mDelayControl;mDelayControl.delay(1000);}std::thread t([&]{char buf[64] = {0};while(true){usleep(RAND(0, 5000) * 1000);system("ntpclient -s -c 1 -h ntp7.aliyun.com -i 3");usleep(RAND(0, 5000) * 1000);snprintf(buf, sizeof(buf), "date -s \"%.4d-%.2d-%.2d %.2d:%.2d:%.2d\"",  RAND(1990, 2030), RAND(1, 12), RAND(1, 29), RAND(0, 23), RAND(1, 60), RAND(1, 60));iprint("set time:[%s]", buf);system(buf);}});t.detach();while(true){int delay = RAND(0, 5000);unsigned long long ms = 0;iprint("delay:-->[%d]", delay);sp_timer_->update();bool isdone = sp_delay_->delay(delay);ms = sp_timer_->getMillisecond();iprint("delay %s:[%d][%d][%lld]", delay != ms ? "delay != ms" : "done", isdone, delay, sp_timer_->getMillisecond());}return 0;
}
http://www.dtcms.com/a/408558.html

相关文章:

  • 网站请及时续费西湖南昌网站建设公司
  • 招标网站免费怎么区别做pc端和手机端网站
  • 制作商务网站wordpress 添加子菜单
  • 上海网站建设选缘魁-企查滕州做网站比较好的网络公司
  • 武夷山景区网站建设特点临沧网站建设临沧
  • 做海报哪个网站好thinkphp5来做网站吗
  • 河北雄安新区规划建设局网站宜选科技就是帮人做网站
  • 焦作网站建设兼职洛阳市做网站贴吧
  • 移动网站开发书籍江苏扬州建设工程信息网站
  • 网站如何适应屏幕现在pc端网站开发用的什么技术
  • 网站制作公司很好 乐云践新快速做效果图的网站叫什么
  • 黄石市建设局网站湖南众诚建设 官方网站
  • 自己做装修网站需要多少钱上海网址大全
  • [嵌入式embed]Keil5-STM32F103C8T6(江协科技)+移植FreeRTOS v9模版项目
  • 做窗帘的效果图网站那些因素会影响网站的排名位置
  • 惠州做网站哪家公司好wordpress吗
  • 网站做好了 后期怎么做企业网站营销优缺点
  • 做电子商务网站 除了域名 网页设计 还有服务器 和网站空间怎样建设网站后台
  • 做网站赚钱不旅游网站的首页怎么做
  • 美的网站建设用ps做网站首页
  • 巢湖网站建设公司东莞黄页大全
  • 公路水运建设质量安全监督网站it外包公司联系电话
  • 做卷皮网类似网站wordpress网站手机端菜单栏
  • 网站开发的解决方案国家城乡和住房建设部网站
  • 网站推广需求学习网站后台维护
  • 肇庆住房和城乡建设局网站建设局是个好单位吗
  • 简单建优化网站无需技术php网站服务器搭建
  • 然后建设一个论坛网站外贸网站建设是什么
  • 网站建设方案书阿里云高清图片素材网站推荐
  • 广东网站设计服务商怎么制作表白链接