0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シンプルな名前付きMutexで排他制御

Posted at

はじめに

複数プロセス間でリソースを排他制御するため名前付きMutexで作ってみました。
環境はWindows、C言語です。

コード

C
// mutexのテスト

// 「シグナル状態」とは、そのミューテックスオブジェクトが
// どのスレッドにも所有されていない、つまりリソースが
// 利用可能である状態

#include <windows.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define PRINT_WITH_TIME(fmt, ...)                               \
    do                                                          \
    {                                                           \
        time_t rawtime;                                         \
        struct tm *timeinfo;                                    \
        char buffer[9];                                         \
        time(&rawtime);                                         \
        timeinfo = localtime(&rawtime);                         \
        strftime(buffer, sizeof(buffer), "%H:%M:%S", timeinfo); \
        printf("[%s] " fmt, buffer, ##__VA_ARGS__);             \
    } while (0)


int main()
{
    HANDLE hMutex, oMutex;
    BOOL ret;
    DWORD res;
    char *mutexName = "NameOfMutexObject";

    // createMutex
    hMutex = CreateMutex(NULL, FALSE, mutexName);
    PRINT_WITH_TIME("called CreateMutex(). hMutex=0x%x\n", hMutex);
    if (hMutex == NULL) {
        printf("CreateMutex() エラー GetLastError: %d\n", GetLastError());
        exit(-1);
    }

    // WaitForSingleObject
    PRINT_WITH_TIME("before call WaitForSingleObject().\n");
    res = WaitForSingleObject(hMutex, INFINITE);
    PRINT_WITH_TIME("after  call WaitForSingleObject(). Result=0x%x\n", res);
    if (res != WAIT_OBJECT_0) {
        printf("WaitForSingleObject() エラー GetLastError: %d\n", GetLastError());
        exit(-1);
    }

    // OpenMutex
    oMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexName);
    PRINT_WITH_TIME("called OpenMutex(). hMutex=x%x\n", oMutex);
    if (oMutex == NULL) {
        printf("OpenMutex() エラー GetLastError: %d\n", GetLastError());
        exit(-1);
    }

    /* 実際はファイル更新操作 */
    sleep(15);

    // CloseHandle
    ret = CloseHandle(oMutex);
    PRINT_WITH_TIME("called CloseHandle(). ret=0x%x\n", ret);
    if (ret == 0) {
        printf("CloseHandle() エラー. GetLastError: %d\n", GetLastError());
        exit(-1);
    }

    // ReleaseMutex
    ret = ReleaseMutex(hMutex);
    PRINT_WITH_TIME("called ReleaseMutex(). ret=0x%x\n", ret);
    if (ret == 0) {
        printf("ReleaseMutex() エラー. GetLastError: %d\n", GetLastError());
        exit(-1);
    }

    return 0;
}

実行結果

コードをビルドして、a.exeを作成。2つのコマンドプロンプトを起動し、それぞれほぼ同時にa.exeを起動する。

コマンドプロンプト1
>a.exe
[13:29:26] called CreateMutex(). hMutex=0xa4
[13:29:26] before call WaitForSingleObject().
[13:29:26] after  call WaitForSingleObject(). Result=0x0
[13:29:26] called OpenMutex(). hMutex=xa8
[13:29:41] called CloseHandle(). ret=0x1
[13:29:41] called ReleaseMutex(). ret=0x1

>
コマンドプロンプト2
>a.exe
[13:29:28] called CreateMutex(). hMutex=0xa4
[13:29:28] before call WaitForSingleObject().
[13:29:41] after  call WaitForSingleObject(). Result=0x0
[13:29:41] called OpenMutex(). hMutex=xb4
[13:29:56] called CloseHandle(). ret=0x1
[13:29:56] called ReleaseMutex(). ret=0x1

>

確かに、コマンドプロンプト2で実行したa.exeがウェイトしているのを確認。
以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?