Closed Z-eddy closed 1 year ago
@Z-eddy
master 代码已经支持所述功能,可以试试
由于增加了关闭状态,以及支持在协程、线程中混用channel,不能再用 co::timeout()
判断读写操作是否超时。
co::chan<fastring> ch(8, 32);
ch << fastring("hello");
if (ch.done()) {
COUT << "write to channel ok..";
}
fastring s;
ch >> s;
if (ch.done()) {
COUT << "read from channel ok, s: " << s;
}
ch.close();
if (!ch) {
COUT << "channel was closed..";
}
已经尝试了下,存在这个问题: 使用ch.close()后会立即关闭通道,此时ch中还存在最后一个数据,使用ch.done()进行判断,因为通道关闭,无法读取到最后一个数据。测试代码如下:
co::Chan<std::string> ch;
// 写入数据
go([=] {
for (int i{0}; i != 10; ++i) {
std::string tempVal{};
tempVal = "current:" + std::to_string(i);
ch << tempVal;
}
ch.close();
});
// 读取数据
go([=] {
std::string val{};
while (ch.done()) {
ch >> val;
std::cout << val << std::endl;
}
std::cout << "done";
});
输出结果: current:0 current:1 current:2 current:3 current:4 current:5 current:6 current:7 current:8 done
需求不明确,channel close 后 可以读、不能写?
chan::done()
用于判断读写操作是否正常完成,判断channel是否关闭直接用 while(ch)
这里写入通道的数据i是0~9
for (int i{0}; i != 10; ++i) {
std::string tempVal{};
tempVal = "current:" + std::to_string(i);
ch << tempVal;
}
ch.close();
读取这里只能收到0~8
while (ch.done()) {
ch >> val;
std::cout << val << std::endl;
}
最后的9无法收到,数据丢失了1个
重新调整了设计方案,chan close 后可以读,但不能写。
done()
需要在读、写操作后调用,判断读、写是否正常完成。
co::chan<std::string> ch;
// 写入数据
go([=] {
for (int i{0}; i != 10; ++i) {
ch << ("current:" + std::to_string(i));
}
ch.close();
});
// 读取数据
go([=] {
std::string val{};
do {
ch >> val;
std::cout << val << std::endl;
} while (ch.done())
std::cout << "done";
});
测试了下你给的这个demo,最后一个数据9会输出两次,且如果在写入数据那直接调用close,会收到一个空字符串:
co::chan<std::string> ch;
// 写入数据
go([=] {
// 直接调用关闭
ch.close();
});
// 读取数据
go([=] {
std::string val{};
do {
ch >> val;
std::cout << val << std::endl;
} while (ch.done());
std::cout << "done";
});
按照使用习惯,可能这样的读取数据写法会更方便点(这种写法不会输出最后的9):
// 读取数据
go([=] {
std::string val{};
while (ch) {
ch >> val;
std::cout << val << std::endl;
}
std::cout << "done";
});
就像go中这样的用法:
func readData(ch chan int) {
for num := range ch {
fmt.Println(num)
}
}
func writeData(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}
func main() {
ch := make(chan int)
go writeData(ch)
readData(ch)
}
@Z-eddy 并没有重复,只是最后一次读失败,未加判断
co::chan<std::string> ch;
// 写入数据
go([=] {
for (int i{0}; i != 10; ++i) {
ch << ("current:" + std::to_string(i));
}
ch.close();
});
// 读取数据
go([=] {
std::string val{};
do {
ch >> val;
if (ch.done()) std::cout << val << std::endl;
} while (ch.done())
std::cout << "done";
});
加上判断后没问题了,你们好效率啊!
库写的很棒,希望能增加类似go判定通道已经关闭这个功能: 协程0 消费者:
协程1 生产者: