数学とプログラミングとくだらないこと

プログラミングの事とか数学のこととかを書いていきます。

共有ライブラリのグローバル変数は他のプロセスからでも参照できるのか?

共有オブジェクトファイルのグローバル変数へのアクセスってどうなってるんだろう? という事で、実験してみました。

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とかが他のプロセスから書き換えられたら困るもんな…

きっと親子のプロセスでなく、兄弟のプロセスだったら、出力される値は同じになるはず。

この実験はいつかやろう(やらないパターン。)