20

いくつかのプロセス(フォーク)を生成し、POSIX共有メモリを介して通信するLinuxプログラムがあります。各プロセスにID(0〜255)を割り当ててもらいたいのですが。私の意図は、ビットベクトルを共有メモリ領域(ゼロに初期化)に配置し、ビットをアトミックに比較して交換し、IDを割り当てることです。

これを行うためのc++11に適した方法はありますか?アトミックビットセットを作成できますか?プロセス間でミューテックスを使用できますか?コンストラクターがすべてのプロセスで一度だけ呼び出されるようにするにはどうすればよいですか?

4

2 に答える 2

19

C ++ 11スレッドプリミティブ(ミューテックス、アトミックなど)はスレッドプリミティブです。C ++標準はプロセスを参照せず、これらのツールのほとんどはプロセス間で相互運用しません。

標準でのプロセスの唯一の言及は、ロックフリーアトミックがIPCでOKであることを意図していることを示す非規範的な表記法です:

ロックフリーの操作もアドレスフリーである必要があります。つまり、2つの異なるアドレスを介した同じメモリ位置でのアトミック操作は、アトミックに通信します。実装は、プロセスごとの状態に依存しないようにする必要があります。この制限により、プロセスに複数回マップされたメモリと、2つのプロセス間で共有されたメモリによる通信が可能になります。

この非規範的な表記法以外では、スレッドプリミティブはプロセス間通信を実現する手段となることを意図していません。共有メモリに配置されたときのそのようなオブジェクトの動作(上記のロックフリーアトミックを除く)は定義されていません。

于 2012-10-31T17:19:45.817 に答える
8

共有メモリブロック内でミューテックスを使用できますが、ミューテックスはSHAREDとして宣言する必要があるため、共有メモリ内でミューテックスを使用することは珍しくありません。独自のクラスを作成できます。これは非常に簡単です。

class Mutex {
private:
    void *_handle;
public:
    Mutex(void *shmMemMutex,  bool recursive =false, );
    virtual ~Mutex();

    void lock();
    void unlock();
    bool tryLock();
};

Mutex::Mutex(void *shmMemMutex, bool recursive)
{
    _handle = shmMemMutex;
    pthread_mutexattr_t attr;
    ::pthread_mutexattr_init(&attr);
    ::pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    ::pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE_NP : PTHREAD_MUTEX_FAST_NP);

    if (::pthread_mutex_init((pthread_mutex_t*)_handle, &attr) == -1) {
        ::free(_handle);
        throw ThreadException("Unable to create mutex");
    }
}
Mutex::~Mutex()
{
    ::pthread_mutex_destroy((pthread_mutex_t*)_handle);
}
void Mutex::lock()
{
    if (::pthread_mutex_lock((pthread_mutex_t*)_handle) != 0) {
        throw ThreadException("Unable to lock mutex");
    }
}
void Mutex::unlock()
{
    if (::pthread_mutex_unlock((pthread_mutex_t*)_handle) != 0) {
        throw ThreadException("Unable to unlock mutex");
    }
}
bool Mutex::tryLock()
{
    int tryResult = ::pthread_mutex_trylock((pthread_mutex_t*)_handle);
    if (tryResult != 0) {
        if (EBUSY == tryResult) return false;
        throw ThreadException("Unable to lock mutex");
    }
    return true;
}
于 2013-11-11T14:35:54.480 に答える