3

futex ロックで待機しているスレッドを起こすことは可能でしょうか? シグナル メカニズムを使用してみましたが、機能していないようです。私が試すことができる他のアプローチはありますか?以下に、私が達成しようとしていることに似ているかもしれない例を追加しました。

  1. 次のようにfutexロック「lockA」を取得するスレッドAがあります:- ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);

  2. スレッド A がロックを取得したため、futex ロック「lockA」を取得しようとするスレッド B とカーネル内のブロックがあります。 ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);

  3. スレッド B が lockA を取得すると、別のスレッドであるスレッド C がそれを認識します。スレッド B がロックを取得しない場合、スレッド C はスレッド B がロックの待機を停止し、別のことを行うことを望みます。

基本的に、この時点で、カーネルでブロックされないように、スレッド C をスレッド B に「シグナル」させることができるかどうかを調べようとしています。そのために、次のようにスレッド B にシグナル ハンドラーを設定します。

struct sigaction act;

act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGSYS, &act, NULL);

...
...

void handler() {
  fprintf(stderr, "Inside the handler, outta the kernel\n");
}

スレッド CI から次のようにシグナルを送信してみてください:- pthread_kill(tid_of_B, SIGSYS);

私は何を間違っていますか?スレッド B を起動することはできますか? もしそうなら、別のアプローチを使用する必要がありますか?

[編集] 以下のコメントに基づいて、pthread_kill からの戻り値を確認しようとしたところ、呼び出しが返されていないことに気付きました。

4

1 に答える 1

0

いくつかのこと。

マニュアルページにないものを使用しFUTEX_LOCK_PIています。カーネル ソースとドキュメントを見たところ、このバージョンはカーネル内でのみ使用されるようです。カーネルの代わりとして「PI ミューテックス」を実装するために使用されます。spinlock

を使用する場合はfutex、それが指すアドレス内のデータにセマンティクスを実装する必要があります。

以下は、大まかな疑似コードで、おそらく/おそらく間違っている例です。

int mysem = 1;

void
lock(void)
{

    // atomic_dec returns new value
    while (1) {
        if (atomic_dec(&mysem) == 0)
            break;
        futex(&mysem,FUTEX_WAIT,...)
    }
}

void
unlock(void)
{

    // non_atomic_swap returns old value
    if (non_atomic_swap(&mysem,1) != 0)
        futex(&mysem,FUTEX_WAKE,...)
}
于 2015-11-16T21:03:21.690 に答える