質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.23%

sem_getvalue()は成功するのにsem_wait()で失敗します

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 3,528

kutsulog

score 963

スレッドの初期化処理完了を待つため、
sem_wait(&thread_inf[cnt].sem)を使っているのですが、
実行結果が失敗になります。(strerror(errno)の結果は[Invalid argument]になります)
確認のため、直前で
sem_getvalue(&thread_inf[cnt].sem, &val)を実行すると、
こちらは成功します。
(遅れて実行されるスレッド側のsem_post(&thread_inf[cnt].sem)も返り値は成功になります)

このthread_infはグローバル変数として宣言して使用しているのですが、
どこかまずいところがあるのでしょうか?

原因・対応がわかりましたら、回答お願いいたします。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

それぞれのthread_inf[cnt].semに対して、sem_initもしくはsem_openをする必要があるのではないでしょうか。


sem_initでの例を書いてみました。

(GCC 4.8.3 Cygwinを使用)

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;

void *thread_f();

int main()
{
  pthread_t th;
  int shared;
  unsigned int value;
  int r;

  shared = 1;
  value = 0;

  r = sem_init(&sem, shared, value);
  printf("r=%d, err=%s\n", r, strerror(errno));

  r = sem_getvalue(&sem, &value);
  printf("r=%d, err=%s\n", r, strerror(errno));

  if (pthread_create(&th, NULL, thread_f, (void *)NULL))
  {
    printf("スレッドの生成に失敗\n");
    return 1;
  }

  printf("sem_wait\n");
  r = sem_wait(&sem);
  printf("r=%d, err=%s\n", r, strerror(errno));

  return 0;
}

void *thread_f() {
  sleep(5);
  printf("sem_post\n");
  sem_post(&sem);
  return (void *)NULL;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2014/11/27 23:16

    構造体の中が壊れていて、順番を変えたら発現しなくなったというのは、thread_infのアロケートに問題があるのかも知れません。
    Windowsからに限らず、移植前はたまたま動いていたのが新しいOSに移植したら問題が顕在化したというケースはよくあります。

    キャンセル

  • 2014/12/07 11:09

    thread_infの宣言は
    HOGE thread_inf[THREAD_MAX_SIZE]で宣言しています。
    (reallocなどはしておらず、THREAD_MAX_SIZEは今のところ1です)

    初期化は最初にmemset( &thread_inf[cnt], 0x00, sizeof(HOGE))した後
    それぞれの値を設定して使っています。

    セマフォ変数はもともとWindows時代は
    EventのPOST,WAITしていたところの代替で
    今回の移植から使っています。

    キャンセル

  • 2014/12/07 16:45

    そうですか...他に考えられるとしたら、BlueMoonさんもおっしゃっていますが、セマフォ―関数とは無関係の何かしらの破壊的操作があるのでは?、くらいでしょうか。
    地道にすべてのthread_infの操作前後で状態を見ていくしか思いつきません。
    お役にたてずにすみません。

    キャンセル

+1

thread_inf[cnt].semの値をログ出力などして、sem_init実行直後とsem_wait実行時で比較してみてはどうでしょうか。配列添え字のcntの値も気になります。

不要な説明かも知れませんがセマフォについてです。sem_はそのライブラリ関数になります。スレッドは並列実行されるので共通資源へのアクセス(共通の初期化処理、スレッド共通の変数へのアクセス等)に排他制御が必要になるのかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2014/12/07 10:57

    init/wait/post
    それぞれの前(initは後)で値とアドレスをprintfして確認しましたが、
    問題はありませんでした。
    添字cntはforでそれぞれ初期化するために使っていますが、
    for( int cnt = 0; cnt < 1; cnt++ )でも失敗しました。

    キャンセル

  • 2014/12/07 13:18

    別回答のコメントを見ますところ、構造体内のsem_tの位置を変えて成功したということであれば、構造体の他メンバを使用している処理が領域破壊している可能性が高いと思います。
    思いつく調査方法は、関係処理をコメントアウトするなどして被疑部分を絞りこんでみる等です。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る