C++ C++;如何冲洗std:stringbuf?
我需要将进程的标准输出(二进制数据)放入字符串缓冲区,并在另一个线程中使用它 以下是制作人:C++ C++;如何冲洗std:stringbuf?,c++,multithreading,streambuf,C++,Multithreading,Streambuf,我需要将进程的标准输出(二进制数据)放入字符串缓冲区,并在另一个线程中使用它 以下是制作人: while (ReadFile(ffmpeg_OUT_Rd, cbBuffer, sizeof(cbBuffer), &byteRead, NULL)){ tByte += byteRead; //total bytes sb->sputn(cbBuffer, byteRead); } m_bIsFinished = true; printf("%d bytes are
while (ReadFile(ffmpeg_OUT_Rd, cbBuffer, sizeof(cbBuffer), &byteRead, NULL)){
tByte += byteRead; //total bytes
sb->sputn(cbBuffer, byteRead);
}
m_bIsFinished = true;
printf("%d bytes are generated.\n", tByte);
以下是消费者:
while (!PCS_DISPATCHER_INSTANCE->IsFinished())
Sleep(200);
Sleep(5000);
Mystringbuf* sb = PCS_DISPATCHER_INSTANCE->sb;
printf("Avail: %d\n", sb->in_avail());
事实证明,使用者无法获取生产者生成的所有字节。
(tbytesb->in\u avail()
)
这是一种内部缓冲问题吗?如果是,如何强制stringbuf刷新其内部缓冲区?A没有类似于刷新的功能:写入操作直接写入缓冲区。如果您使用诸如filebuf之类的派生对象,则有一个成员可以提供帮助。但这不适用于你的情况
您的问题当然来自于一场数据竞赛on或is\u avail()
。可以通过互斥锁保护对streambuf的访问,也可以通过。如果m_bIsFinished
不是原子,并且取决于isFinished()
的实现,线程之间的同步可能无法得到保证(例如:生产者可以写入内存,但消费者仍然从CPU内存缓存中获取过时的值),这可能导致这样的数据竞争
编辑:
如果您在单个线程中遇到此问题,从而消除了任何潜在的竞速情况,那么它可能来自streambuf
的实现。我可以在单线程应用程序中体验MSVC13:
- 跟踪显示读取的字节数是准确的,但在整个循环中,
结果始终小于或等于tByte李>in_avail()
- 读取streambuf时,读取了正确的总字节数(因此超过in_avail()所指示的字节数)李>
in_avail()
字节,而不会遇到eof
解决方法使用
sb->pubsekoff(0,ios::end)-sb->pubsekoff(0,ios::beg)
计算可用字节数,并确保在读取streambuf之前重新定位到sb->pubseekoff(0,ios::beg) m_>是原子的还是原子的?睡眠不是同步原语。你需要一个。@Christophe Nope,只是一个原始布尔值。我试图用同样的printf(“%d,%d\n”,tByte,sb->in_-avail())打印输入值和从管道读取的字节数代码>它们给出了相同的值是的,但是我已经让消费者线程休眠了5秒钟,所以我猜还有一些其他问题?太好了!这很有效。我原以为in_avail()会像它的名字所描述的那样工作。