How to do it...

In this recipe, we will create a sample application that creates two processes. One process generates data while another reads the data and prints it to the console:

  1. In your working directory (~/test), create a subdirectory called ipc1.
  2. Use your favorite text editor to create an ipc1.cpp file in the ipc1 subdirectory.
  3. We are going to define two templated classes to organize our data exchange. The first class, Writer, is used to write data into a file. Let's put its definition in the ipc1.cpp file:
#include <fstream>
#include <iostream>
#include <thread>
#include <vector>

#include <unistd.h>

std::string kSharedFile = "/tmp/test.bin";

template<class T>
class Writer {
private:
std::ofstream out;
public:
Writer(std::string& name):
out(name, std::ofstream::binary) {}

void Write(const T& data) {
out.write(reinterpret_cast<const char*>(&data), sizeof(T));
}
};
  1. This is followed by the definition of the Reader class, which is responsible for reading data from a file:
template<class T>
class Reader {
private:
std::ifstream in;
public:
Reader(std::string& name) {
for(int count=10; count && !in.is_open(); count--) {
in.open(name, std::ifstream::binary);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}

T Read() {
int count = 10;
for (;count && in.eof(); count--) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

T data;
in.read(reinterpret_cast<char*>(&data), sizeof(data));
if (!in) {
throw std::runtime_error("Failed to read a message");
}
return data;
}
};
  1. Next, we define the data type that we will use for our data:
struct Message {
int x, y;
};

std::ostream& operator<<(std::ostream& o, const Message& m) {
o << "(x=" << m.x << ", y=" << m.y << ")";
}
  1. To wrap everything together, we define the DoWrites and DoReads functions, as well as the main function that invokes them:
void DoWrites() {
std::vector<Message> messages {{1, 0}, {0, 1}, {1, 1}, {0, 0}};
Writer<Message> writer(kSharedFile);
for (const auto& m : messages) {
std::cout << "Write " << m << std::endl;
writer.Write(m);
}
}

void DoReads() {
Reader<Message> reader(kSharedFile);
try {
while(true) {
std::cout << "Read " << reader.Read() << std::endl;
}
} catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl;
}
}

int main(int argc, char** argv) {
if (fork()) {
DoWrites();
} else {
DoReads();
}
}
  1. Finally, create a CMakeLists.txt file containing the build rules for our program:
cmake_minimum_required(VERSION 3.5.1)
project(ipc1)
add_executable(ipc1 ipc1.cpp)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

SET(CMAKE_CXX_FLAGS "--std=c++11")

set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)

You can now build and run the application. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.245.196