こんにちは。RockinWoolです。最近外付けHDDの挙動がおかしかったので、もう一つ買ってきました。これで完璧。
さて、今回はGRPC! と行きたいところです。ただ、そもそものC++周りの知識が全然無かったので、ひたすらそれを書いていこうかなという感じです。
- #1. gRPCを使ってプロセス間通信を実現する参考1
まずは今回の目的であるgRPCの導入と、gRPCを使用する際に必要になるprotobufが使えるようにならないといけない。なので、そのあたりの環境構築からはじめる.参考2
最初にcmakeのインストールを行う
export MY_INSTALL_DIR=$HOME/.local
wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh
sh cmake-linux.sh -- --skip-license --prefix=$MY_INSTALL_DIR
rm cmake-linux.sh
cmake --version
次にgRPCのインストールを行う。まずはパス通しから
export MY_INSTALL_DIR=$HOME/.local
mkdir -p $MY_INSTALL_DIR
export PATH="$PATH:$MY_INSTALL_DIR/bin"
.~bashrcにも追記する
export PATH=$PATH:$HOME/.local/bin
そして関連ツールのインストール
sudo apt-get install build-essential autoconf libtool pkg-config libssl-dev
そしてgRPCをクローンしてきてひたすらmakeする.
ただし普通にビルドするとPCに負荷がかかり過ぎてフリーズすることがあった。そのため、cgroupで制約を課しながら、システムに余裕を持たせて実行すると良い。\
sudo apt install cgroup-tools
cgroup-toolsをインストールしたら、/etc/cgconfig.confを作成して、以下のように入力する
group g1{
memory{
memory.limit_in_bytes=2G;
}
}
最後に設定を反映させたターミナルを起動する
sudo cgconfigparser -l /etc/cgconfig.conf
sudo cgexec -g memory:g1 gnome-terminal
su $一般ユーザー
ターミナルが起動したら作業ディレクトリまで移動したのち、以下のコマンドを実行してビルドを行う
export MY_INSTALL_DIR=$HOME/.local
git clone --recurse-submodules -b v1.35.0 https://github.com/grpc/grpc
cd grpc
mkdir -p cmake/build
pushd cmake/build
cmake -DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
../..
make
make install
popd
mkdir -p third_party/abseil-cpp/cmake/build
pushd third_party/abseil-cpp/cmake/build
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
-DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \
../..
make
make install
popd
最後になぜかパーミッションがおかしい.pcファイルたちを移動しつつ権限を変更する
sudo cp ~/.local/lib/pkgconfig/*.pc /usr/local/lib/pkgconfig/
sudo chmod 664 /usr/local/lib/pkgconfig/*
それとPKG_CONFIG_PATHを指定しておかないと.pcファイルを読んでくれないので、これも指定する
export PKG_CONFIG_PATH=~/.local/lib/pkgconfig/
いちおうbashrcにも書いておく。
PKG_CONFIG_PATH=~/.local/lib/pkgconfig/
ここまでで、ようやくgrpcの作成環境が整えることができた。次はプログラミングである。ディレクトリ構成を以下のようにする
(root) /
proto / (.protoファイルを置くためのディレクトリ)
server / (C++で書かれたserverのソースを置くためのディレクトリ)
client / (Pythonで書かれたclientのソースを置くディレクトリ)
このprotoディレクトリ内にrandom_walker.protoを用意する
syntax = "proto3";
package random_walker;
service MyRandomWalker {
rpc Update (NumSteps) returns (Empty) {}
rpc GetPosition (Empty) returns (Position) {}
}
message Empty {
}
message NumSteps {
int32 n = 1;
}
message Position {
int32 x = 1;
}
これを以下のコマンドでcppとhに変換する
protoc -I ../proto --cpp_out=. ../proto/random_walker.proto
protoc -I ../proto --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../proto/random_walker.proto
これで生成されるproto/random_walker.grpc.pb.hを見ると、134-140行目に関数の定義がされている
class Service : public ::grpc::Service {
public:
Service();
virtual ~Service();
virtual ::grpc::Status Update(::grpc::ServerContext* context, const ::random_walker::NumSteps* request, ::random_walker::Empty* response);
virtual ::grpc::Status GetPosition(::grpc::ServerContext* context, const ::random_walker::Empty* request, ::random_walker::Position* response);
};