使用 JNA 发送到 POSIX 信号量

我正在尝试在 Linux 机器上使用 JNA 发布到信号量。出于某种原因,即使对于这个简单的示例,我也总是收到 22 错误(无效参数)。以我的理解,下面的代码不应该打开一个 POSIX 信号量,发布到它并再次关闭它吗?


public class Sample {


  private static final int O_CREAT = 0x40;


  public static void main(String[] args) throws Exception {

    File notifier = new File("/tmp", "_test" + new Random().nextInt());

      if (!notifier.isFile() && !notifier.createNewFile()) {

        throw new IllegalStateException("Could not create notifier: " + notifier);

      }


      SempahoreLibrary library = Native.load("c", SempahoreLibrary.class);

      Pointer semaphore = library.sem_open(notifier.getAbsolutePath(), O_CREAT, 666, 0);

      try {

        library.sem_post(semaphore);

      } finally {

        library.sem_close(semaphore);

      }

  }


  interface SempahoreLibrary extends Library {

    Pointer sem_open(String name, int flags, int mode, int value) throws LastErrorException;

    int sem_post(Pointer pointer) throws LastErrorException;

    int sem_close(Pointer pointer) throws LastErrorException;

  }

}


慕少森
浏览 68回答 1
1回答

www说

我最初也不能让它与 JNR 一起工作(强烈推荐而不是 JNA),并且很好奇。用 C 编写它有帮助.. :)C 端口上的 strace 清楚地表明您不必预先创建文件,然后将信号量“映射”到它。使用完整路径也是错误的,因为信号量是在 /dev/shm 中创建的,而路径中的“/”搞砸了一切:futex(0x7f731b1190d0, FUTEX_WAKE_PRIVATE, 2147483647) = 0openat(AT_FDCWD, "/dev/shm/sem.sema", O_RDWR|O_NOFOLLOW) = 3fstat(3, {st_mode=S_IFREG|0644, st_size=32, ...}) = 0因此,您应该能够删除整个文件/路径创建,并在 sem_open 中为信号量使用常规的非路径名称。此外,文件模式应该是八进制的,并且您应该确保还加载了 pthread 库——这是必需的。这是 C 中的一个工作示例:// clang -Wall sema.c -lpthread#include <fcntl.h>#include <sys/stat.h>#include <semaphore.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>int main(int argc, char** argv){&nbsp; &nbsp; sem_t* s = sem_open("notifier", O_CREAT, 0644, 0);&nbsp; &nbsp; if (!s) {&nbsp; &nbsp; &nbsp; &nbsp; perror("sem_open");&nbsp; &nbsp; &nbsp; &nbsp; exit(errno);&nbsp; &nbsp; }&nbsp; &nbsp; printf("s: %p\n", s);&nbsp; &nbsp; sem_post(s);&nbsp; &nbsp; int value = -1;&nbsp; &nbsp; sem_getvalue(s, &value);&nbsp; &nbsp; printf("value: %d\n", value);&nbsp; &nbsp; sem_wait(s);&nbsp; &nbsp; sem_getvalue(s, &value);&nbsp; &nbsp; printf("value: %d\n", value);&nbsp; &nbsp; sem_close(s);&nbsp; &nbsp; exit(EXIT_SUCCESS);}这是一个使用 JNR 的工作 Java 版本:import jnr.ffi.LastError;import jnr.ffi.LibraryLoader;import jnr.ffi.Pointer;import jnr.ffi.Runtime;public class Semaphore{&nbsp; &nbsp; private static final int O_CREAT = 0x40;&nbsp; &nbsp; public interface SempahoreLibrary&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Pointer sem_open(String name, int flags, int mode, int value);&nbsp; &nbsp; &nbsp; &nbsp; int sem_post(Pointer pointer);&nbsp; &nbsp; &nbsp; &nbsp; int sem_close(Pointer pointer);&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) throws Exception&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; LibraryLoader<SempahoreLibrary> loader = LibraryLoader.create(SempahoreLibrary.class);&nbsp; &nbsp; &nbsp; &nbsp; loader.library("c");&nbsp; &nbsp; &nbsp; &nbsp; loader.library("pthread");&nbsp; &nbsp; &nbsp; &nbsp; SempahoreLibrary library = loader.load();&nbsp; &nbsp; &nbsp; &nbsp; jnr.ffi.Runtime runtime = Runtime.getRuntime(library);&nbsp; &nbsp; &nbsp; &nbsp; Pointer semaphore = library.sem_open("notifier", O_CREAT, 0644, 0);&nbsp; &nbsp; &nbsp; &nbsp; if (semaphore == null)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int errno = LastError.getLastError(runtime);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("sem_open: " + errno);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.exit(errno);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("semaphore: " + Long.toHexString(semaphore.address()));&nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int error = library.sem_post(semaphore);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("post: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; finally&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int error = library.sem_close(semaphore);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("close: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java