mirror of
https://github.com/Light-City/CPlusPlusThings.git
synced 2026-10-29 03:14:06 +08:00
- const README: rewrite the space-saving claim per issue #5 follow-ups (constant-expression const vs #define immediates; which const qualify as constant expressions) - const README: fix the class-section diagnosis per issue #338 (overload resolution picks the const overload; the restriction only surfaces once that overload is removed) - sizeof README: virtual-inheritance result is compiler-dependent (GCC merges vbptr+vfptr -> 16, MSVC keeps them separate -> 32) #246 - static README: new section on internal linkage / access restriction with anonymous-namespace comparison #142 - 10-day practice: full problem list table + fixed day links #136 - new design_pattern/singleton/singleton_default.hpp: reusable thread-safe CRTP singleton template, compile+concurrency tested #303
This commit is contained in:
83
site_extras/cpp-projects-cpp-ipc-practice.md
Normal file
83
site_extras/cpp-projects-cpp-ipc-practice.md
Normal file
@@ -0,0 +1,83 @@
|
||||
> 来自 [C++那些事网站](https://light-city.github.io/stories_things/cpp-projects/cpp-ipc-practice/) 的文章,由站点同步脚本导出。
|
||||
|
||||
# C++ 进程间通信实战
|
||||
|
||||
进程间通信是一个非常重要的话题,特别是像一些大型项目都有它的影子,例如:PostgreSQL使用了管道完成copy的进程间通信,那么本节也将基于这个主题,使用C++去搭建一个进程间通过管道通信的demo出来,本节将会结合前面几节讲的内容,给出一个比较完整的实战例子出来:
|
||||
|
||||
- mutex
|
||||
- condition_variable
|
||||
- thread
|
||||
|
||||
注:本节的完整代码会放在星球中。
|
||||
|
||||
首先一个很简单的管道用法为:
|
||||
|
||||
- 创建一个管道
|
||||
|
||||
它会creating a pipe, forking, and invoking the shell.
|
||||
|
||||
```cpp
|
||||
// FILE *popen(const char *command, const char *type);
|
||||
pipe = popen(command.c_str(), "w");
|
||||
```
|
||||
|
||||
- 关闭一个管道
|
||||
|
||||
```cpp
|
||||
// int pclose(FILE *stream);
|
||||
pclose(pipe);
|
||||
```
|
||||
|
||||
接下来我们就只需要往里面写与读了,原理也很简单,例如:
|
||||
|
||||
此时便会把data写入到前面创建的管道中。
|
||||
|
||||
```cpp
|
||||
// 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里面读即可。
|
||||
|
||||
例如:
|
||||
|
||||
```cpp
|
||||
std::thread writer_thread(write_to_pipe);
|
||||
std::thread reader_thread(read_from_pipe);
|
||||
|
||||
writer_thread.join();
|
||||
reader_thread.join();
|
||||
```
|
||||
|
||||
写线程需要做的事情就是调用fwrite丢数据即可
|
||||
|
||||
```cpp
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
同理,读线程取数据:
|
||||
|
||||
```cpp
|
||||
ProcessReader reader("/tmp/pipe");
|
||||
// 读取数据
|
||||
std::string message;
|
||||
while (reader.read(message)) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
最后的效果就是:
|
||||
|
||||
```cpp
|
||||
Read from pipe: Hello pipe!
|
||||
```
|
||||
Reference in New Issue
Block a user