3

2 つの Slackware Linux システムがあり、POSIX セマフォsem_open()呼び出しが errno が 38 に設定されて失敗します。サンプル コードを以下に再現します (コードは CentOS / RedHat で正常に動作します)。

これを引き起こす可能性のあるカーネルまたはシステム構成オプションはありますか? 他の提案?

問題のあるシステムは Slackware 10.1.0 カーネル 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so ですが、同じコードはずっと古い RedHat 9 カーネル 2.4.20 /lib/librt でも動作します。 -2.3.2.so /lib/tls/libpthread-0.29.so. (CentOS 5 カーネル 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so でも動作します)。

man sem_openこの errno はsem_open()、システムでサポートされていないことを意味します。

#define ENOSYS          38      /* Function not implemented */

sem_open()ユーザー空間は動的librtにリンクする場所librtであり、影響を受けるシステムに存在します。

影響を受けるシステムは、POSIX セマフォをサポートすると主張しています:_POSIX_SEMAPHORESは真であり、これをsysconf(_SC_SEMAPHORES)確認します。

ありがとう、キエラン

編集 1: 使用中のソフトウェア バージョンの詳細を追加し、無関係なコメントを削除しました。

編集 2: /dev/shm は正常なシステムにマウントされ、不良なシステムにはマウントされません。これをマウントしても、影響を受けるシステムの動作は変わりませんでした。/dev/shm も必要だと思いますが、その前に sem_open() が失敗しており、strace がこれをサポートしています。

# /* Quick'n'dirty test program to illustrate sem_open failure
#Run this file to auto-build test and run as a.out

# Build
gcc $0 -lrt
if [ $? -ne 0 ] ; then exit ; fi

# Run
$( dirname $0)/a.out
exit
*/

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


int main(int argc, char *argv[]) {

 const char *SEM_NAME = "SHRMEM_SCXL";  /* name of mutex */
 sem_t *mutex = SEM_FAILED;             /* ptr to mutex */

#ifdef _POSIX_SEMAPHORES
  printf("_POSIX_SEMAPHORES %ld\n", _POSIX_SEMAPHORES);
#else
  puts("Undefined");
#endif

 printf("sysconf %s\n", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" );

 mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1);

 if (mutex == SEM_FAILED) printf("Failed %d\n", errno);
 else {
        puts("Success - pause while you check /dev/shm ");
        sleep(5);
        sem_close(mutex);
        sem_unlink(SEM_NAME);
 }
}
4

5 に答える 5

5

/dev/shm はマウントされていますか? 古いバージョンの slackware では、起動時にこのファイルシステムがマウントされていない可能性があります。/etc/fstab から:

tmpfs  /dev/shm  tmpfs  defaults  0   0

編集:結局のところ、それはおそらく問題ではありません。カーネルまたは librt をアップグレードする必要があるだけかもしれません。

Edit2: あなたが使用していると思われる slackware 11 の場合、sem_open に必要と思われる NPTL スレッド ライブラリ (/lib/tls のライブラリ) を使用するには、2.6.13 より新しいカーネルが必要になると思います。仕事。

Edit3: a) /dev/shm をマウントし、b) 環境変数を 2.6.13 に設定することで、私が持っている slackware 11 ボックスで動作させることができましたLD_ASSUME_KERNEL(カーネル バージョン > 2.6.12 は動作します)。カーネルが 2.6.11.11 であっても機能しているように見えますが、スレッドなどの他のものは機能しない可能性があります。

于 2008-11-06T21:33:38.440 に答える
1

古いバージョンのスレッド ライブラリは、プロセス間での POSIX セマフォの共有をサポートしていません。からman sem_init

pshared 引数は、セマフォが現在のプロセスに対してローカルであるか ( pshared がゼロ)、複数のプロセス間で共有されるか ( pshared がゼロではない) を示します。LinuxThreads は現在、プロセス共有セマフォをサポートしていないため、pshared がゼロでない場合、sem_init は常にエラー ENOSYS を返します。

sem_open() は名前付きセマフォを作成するため、常にプロセス間で共有しようとします。

Slackware 10 で sem_init() を使用してプロセス間の匿名セマフォの共有をサポートするには

  • libpthread と (おそらく) librt をアップグレードします。
  • カーネルをアップグレードする

さらに、sem_open() で名前付きセマフォの共有をサポートするため

  • tmpfs として/etc/fstabマウントする行を追加します/dev/shm

    tmpfs /dev/shm tmpfs デフォルト 0 0

  • 実行mount /dev/shmまたは再起動

于 2008-11-07T12:20:19.667 に答える
1

「プロセス共有の sema4 が機能しない」という仮説には、ある程度の意味があります。役に立つというわけではありませんが、時間と傾向がある場合は、次のことを試して、「プロセス共有」の側面が失敗しているのかどうかを確認してください。

  1. 非共有メモリ (スレッド用) で sem_init を使用してセマフォを作成します。動作する場合、sema4s はプロセス内で動作します。

  2. 共有メモリで実験を繰り返します。これにより、プロセス間で機能するかどうかがわかります。sema4 がプロセス間で機能するかどうかを確認するには、実際に sema4 を使用してみる必要があることに注意してください。

于 2008-11-07T16:15:05.717 に答える
0

POSIXメッセージキューを使用していましたが、同じエラーが発生しました。mq_openがerrono 38(ENOSYS)で失敗しました。

回避策は、カーネル構成でPOSIXMESSAGEQUEUEを有効にしてカーネルを再構築することです。

これにより、POSIXメッセージキューをサポートするカーネルが構築され、私にとってはうまくいきました。

于 2010-05-19T07:02:44.897 に答える
0

プロセス間でセマフォを共有するもう 1 つの方法は、SystemV セマフォを使用することです。

これらは、共有 POSIX セマフォが機能しない場合でも機能します (少なくとも上記のシステムでは)。

2 種類のセマフォの使用例については、http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.htmlを参照してください。

于 2008-11-07T16:38:49.427 に答える