小编486*_*-66的帖子

C++低延迟线程异步缓冲流(用于记录) - Boost

问题:

3下面的循环包含已注释掉的代码.我搜索("TAG1","TAG2"和"TAG3")以便于识别.我只是希望while循环在测试的条件下等待,然后继续进行,同时尽可能地减少CPU资源.我首先尝试使用Boost条件变量,但是存在竞争条件.让线程休眠'x'微秒是低效的,因为没有办法精确计时唤醒.最后,boost :: this_thread :: yield()似乎没有做任何事情.可能是因为我在双核系统上只有2个活动线程.具体来说,如何在引入尽可能少的不必要阻塞的同时,使下面的三个标记区域更有效地运行.

背景

目的:

我有一个记录大量数据的应用程序.在分析之后,我发现在日志记录操作上花费了很多时间(将文本或二进制文件记录到本地硬盘上的文件中).我的目标是通过使用线程缓冲流记录器的调用替换非线程直接写入调用来减少logData调用的延迟.

选项探索:

  • 将2005年代的慢速硬盘升级到SSD ......可能.成本并不高昂......但涉及大量工作......超过200台计算机必须升级......
  • 提升ASIO ......我不需要所有的proactor /网络开销,寻找更简单,更轻量级的东西.

设计:

  • 生产者和消费者线程模式,应用程序将数据写入缓冲区和后台线程,然后稍后将其写入磁盘.因此,最终目标是让应用程序层调用的writeMessage函数尽可能快地返回,而数据在以后的某个时间以FIFO顺序正确/完全记录到日志文件中.
  • 只有一个应用程序线程,只有一个编写器线程
  • 基于环形缓冲区.这个决定的原因是使用尽可能少的锁,理想情况......如果我错了,请纠正我......我认为我不需要任何锁.
  • Buffer是一个静态分配的字符数组,但如果出于性能原因需要/期望,可以将其移动到堆中.
  • Buffer有一个开始指针,指向应写入文件的下一个字符.缓冲区有一个结束指针,指向要写入文件的最后一个字符后的数组索引.结束指针NEVER传递开始指针.如果出现大于缓冲区的消息,则编写器等待直到缓冲区清空并直接将新消息写入文件,而不将超大消息放入缓冲区(一旦缓冲区清空,工作线程)不会写任何东西,所以没有争论).
  • writer(工作线程)仅更新环形缓冲区的开始指针.
  • 主(应用程序线程)仅更新环形缓冲区的结束指针,并且当有可用空间时,它仅将新数据插入缓冲区...否则它将等待缓冲区中的空间变为可用或直接按描述写入以上.
  • 工作线程不断检查是否有要写入的数据(由缓冲区启动指针!=缓冲区结束指针时的情况表示).如果没有要写入的数据,一旦应用程序线程将某些东西插入缓冲区,工作线程理想情况下应进入休眠状态并唤醒(并更改缓冲区的结束指针,使其不再指向与开始时相同的索引)指针).我在下面的内容涉及while循环不断检查该条件.这是一种非常糟糕/低效的缓冲区等待方式.

结果:

  • 在我的2009年配备SSD的双核笔记本电脑上,我看到线程/缓冲基准测试与直接写入的总写入时间大约是1:6(0.609秒对0.095秒),但变化很大.通常,缓冲写入基准测试实际上比直接写入慢.我认为可变性是由于等待空间在缓冲区中释放,等待缓冲区清空以及让工作线程等待工作变得可用而实现的可能性差.我已经测量过一些while循环消耗超过10000个周期,我怀疑这些循环实际上是在争夺另一个线程(工作者或应用程序)完成等待计算所需的硬件资源.
  • 输出似乎结账.启用TEST模式并将10的小缓冲区作为压力测试,我将数百MB的输出分开并发现它等于输入.

使用当前版本的Boost进行编译(1.55)

    #ifndef BufferedLogStream_h
    #define BufferedLogStream_h

    #include <stdio.h>
    #include <iostream>
    #include <iostream>
    #include <cstdlib>
    #include "boost\chrono\chrono.hpp"
    #include "boost\thread\thread.hpp"
    #include "boost\thread\locks.hpp"
    #include "boost\thread\mutex.hpp"
    #include "boost\thread\condition_variable.hpp"
    #include <time.h>

    using namespace std;

    #define BENCHMARK_STR_SIZE 128
    #define NUM_BENCHMARK_WRITES 524288
    #define TEST 0
    #define BENCHMARK 1
    #define WORKER_LOOP_WAIT_MICROSEC 20
    #define MAIN_LOOP_WAIT_MICROSEC 10

    #if(TEST)
    #define BUFFER_SIZE 10 
    #else …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading boost asynchronous low-latency

5
推荐指数
1
解决办法
4981
查看次数

Java SimpleDateFormat返回null,但仅在第二次调用时返回

public static void main(String[] args) {
    ParsePosition pp = new ParsePosition(0);
    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    formatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
    String datetoparse = "7/1/2003 00:02:53";
    Date date = formatter.parse(datetoparse, pp);
    System.out.println(date.toString());
    date = formatter.parse(datetoparse, pp);
    System.out.println(date.toString());
}
Run Code Online (Sandbox Code Playgroud)

格式调用在第一次调用时返回正确的值.但是为什么它在第二次调用时返回null(我在解析与第一次调用中相同的字符串)?

java calendar date simpledateformat

0
推荐指数
1
解决办法
848
查看次数