小項目實戰之進程間通信
進程間通信是一個非常重要的話題,特別是像一些大型項目都有它的影子,例如: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源碼剖析之開篇
熱度更新,手把手實現工業級線程池