共有ライブラリのグローバル変数は他のプロセスからでも参照できるのか?
共有オブジェクトファイルのグローバル変数へのアクセスってどうなってるんだろう? という事で、実験してみました。
Macの共有ライブラリ
Macでの共有ライブラリは.dylib
という拡張子で作るらしい。
コンパイラには-dynamiclib
というオプションを付けるようだ。
Linuxならどんなオプションが必要だったっけ?
コード
実験に使ったコード。
共有ライブラリ用のヘッダファイル(share.h)
実験では、このshare_int32
の値を
親子2つの別のプロセスから書き換えます。
結果の確認のためにprint_share_int32
という関数を作ってます。
/* share.h */
#ifndef SHARE_H
#define SHARE_H
#include <stdint.h>
#include <stdio.h>
extern int32_t share_int32;
void print_share_int32(void);
#endif
共有ライブラリのコード(share.c)
説明略
#include "share.h"
int32_t share_int32 = 0;
void print_share_int32(void)
{
printf("share_int32: %d\n", share_int32);
}
ライブラリを利用する側のコード(main.c)
親プロセスと子プロセスから変数を書き換えてみるコード。
#include "share.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
// グローバル変数を読めるかの確認
print_share_int32();
// グローバル変数に書き込めるかの確認
share_int32++;
print_share_int32();
// 子プロセスでの書き込みが親プロセスで反映されるかの確認
pid_t pid = fork();
if(pid == -1)
{
perror("fork");
exit(1);
}
if(pid == 0)
{
share_int32++;
printf("Child Process: ");
print_share_int32();
exit(0);
}
wait(NULL);
printf("Parent Process: ");
print_share_int32();
return(0);
}
出力
$ clang -dynamiclib -o libshare.dylib share.c
$ clang -o main main.c -L./ -lshare
$ ./main
share_int32: 0
share_int32: 1
Child Process: share_int32: 2
Parent Process: share_int32: 1
考察
子プロセスでインクリメントすると、子プロセスではインクリメントされた値が確認出来るけど、 親プロセスではそうではない。 多分グローバル変数はプロセスごとに別の物なんだろう。
errno
とかが他のプロセスから書き換えられたら困るもんな…
きっと親子のプロセスでなく、兄弟のプロセスだったら、出力される値は同じになるはず。
この実験はいつかやろう(やらないパターン。)