小项目实战之进程间通信
进程间通信是一个非常重要的话题,特别是像一些大型项目都有它的影子,例如:PostgreSQL使用了管道完成copy的进程间通信,那么本节也将基于这个主题,使用C++去搭建一个进程间通过管道通信的demo出来,本节将会结合前面几节讲的内容,给出一个比较完整的实战例子出来:
mutex
condition_variable
thread
注:本节的完整代码会放在星球中。
首先一个很简单的管道用法为:
创建一个管道
它会creating a pipe, forking, and invoking the shell.
// FILE *popen(const char *command, const char *type);
pipe = popen(command.c_str(), "w");
关闭一个管道
// int pclose(FILE *stream);
pclose(pipe);
接下来我们就只需要往里面写与读了,原理也很简单,例如:
此时便会把data写入到前面创建的管道中。
// size_t fwrite( const void* buffer, size_t size, size_t count, FILE* stream );
size_t written = fwrite(data.c_str(), sizeof(char), data.size(), pipe);
如果从管道中读取,我们可以使用fread或者fgets,fgets
会在读取到换行符或达到缓冲区大小时停止,而 fread
会尽可能多地读取数据,直到达到指定的字节数或遇到文件结尾。同理,上面的fwrite可以替换为fputs。
现在,一个管道的基本使用介绍完了,如何写一个完整的demo?
很简单,我们只需要创建两个线程,一个读,一个写,然后写线程往pipe里面写数据,读线程从pipe里面读即可。
例如:
std::thread writer_thread(write_to_pipe);
std::thread reader_thread(read_from_pipe);
writer_thread.join();
reader_thread.join();
写线程需要做的事情就是调用fwrite丢数据即可
ProcessWriter writer("cat > /tmp/pipe");
// 写入数据
std::string message = "Hello pipe!\n";
if (!writer.write(message)) {
std::cerr << "Failed to write data to pipe" << std::endl;
}
同理,读线程取数据:
ProcessReader reader("/tmp/pipe");
// 读取数据
std::string message;
while (reader.read(message)) {
// do something
}
最后的效果就是:
Read from pipe: Hello pipe!
跟我一起实践写代码,戳这里呀~
往期推荐:
向量数据库milvus源码剖析之开篇
热度更新,手把手实现工业级线程池