Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JNA发布到POSIX信号量_Java_Semaphore_Jna - Fatal编程技术网

Java 使用JNA发布到POSIX信号量

Java 使用JNA发布到POSIX信号量,java,semaphore,jna,Java,Semaphore,Jna,我试图在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

我试图在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;
  }
}

起初,我也无法让它与JNR一起工作(强烈建议不要使用JNA),于是我感到好奇。用C编写它有助于……)

C端口上的一个strace清楚地表明,您不必预先创建文件和 然后将信号量“映射”到它。使用完整路径也是错误的,因为 在/dev/shm中创建信号量,并在路径中创建“/” 把一切都收拾好:

futex(0x7f731b1190d0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/dev/shm/sem.sema", O_RDWR|O_NOFOLLOW) = 3
fstat(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)
{
    sem_t* s = sem_open("notifier", O_CREAT, 0644, 0);

    if (!s) {
        perror("sem_open");
        exit(errno);
    }

    printf("s: %p\n", s);

    sem_post(s);

    int value = -1;
    sem_getvalue(s, &value);
    printf("value: %d\n", value);

    sem_wait(s);
    sem_getvalue(s, &value);
    printf("value: %d\n", value);

    sem_close(s);

    exit(EXIT_SUCCESS);
}
//clang-Wall sema.c-lpthread
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
sem_t*s=sem_open(“通知者”,O_CREAT,0644,0);
如果(!s){
perror(“sem_open”);
出口(errno);
}
printf(“s:%p\n”,s);
教统局局长职位;;
int值=-1;
sem_getvalue(s和value);
printf(“值:%d\n”,值);
sem_wait(s);;
sem_getvalue(s和value);
printf(“值:%d\n”,值);
sem_关闭(s);
退出(退出成功);
}
下面是一个使用JNR的工作Java版本:

import jnr.ffi.LastError;
import jnr.ffi.LibraryLoader;
import jnr.ffi.Pointer;
import jnr.ffi.Runtime;

public class Semaphore
{
    private static final int O_CREAT = 0x40;

    public interface SempahoreLibrary
    {
        Pointer sem_open(String name, int flags, int mode, int value);
        int sem_post(Pointer pointer);
        int sem_close(Pointer pointer);
    }

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

        LibraryLoader<SempahoreLibrary> loader = LibraryLoader.create(SempahoreLibrary.class);
        loader.library("c");
        loader.library("pthread");

        SempahoreLibrary library = loader.load();
        jnr.ffi.Runtime runtime = Runtime.getRuntime(library);

        Pointer semaphore = library.sem_open("notifier", O_CREAT, 0644, 0);
        if (semaphore == null)
        {
            int errno = LastError.getLastError(runtime);
            System.out.println("sem_open: " + errno);
            System.exit(errno);
        }

        System.out.println("semaphore: " + Long.toHexString(semaphore.address()));

        try
        {
            int error = library.sem_post(semaphore);
            System.out.println("post: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));
        }
        finally
        {
            int error = library.sem_close(semaphore);
            System.out.println("close: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));
        }
    }
}
导入jnr.ffi.LastError;
进口jnr.ffi.LibraryLoader;
导入jnr.ffi.Pointer;
导入jnr.ffi.Runtime;
公共类信号量
{
私有静态final int O_CREAT=0x40;
公共接口Sempahore图书馆
{
指针sem_open(字符串名称、int标志、int模式、int值);
int sem_post(指针);
int sem_close(指针);
}
公共静态void main(字符串[]args)引发异常
{
LibraryLoader loader=LibraryLoader.create(SempahoreLibrary.class);
加载程序库(“c”);
库(“pthread”);
SempahoreLibrary=loader.load();
jnr.ffi.Runtime Runtime=Runtime.getRuntime(库);
指针信号量=library.sem_open(“通知程序”,O_CREAT,0644,0);
if(信号量==null)
{
int errno=LastError.getLastError(运行时);
System.out.println(“sem_open:+errno”);
系统退出(错误号);
}
System.out.println(“信号量:+Long.toHexString(信号量.地址()));
尝试
{
int error=library.sem\u post(信号量);
System.out.println(“post:”+(error==0?“确定”:LastError.getLastError(运行时));
}
最后
{
int error=library.sem\u close(信号量);
System.out.println(“关闭:”+(错误==0?“确定”:LastError.getLastError(运行时));
}
}
}

谢谢,我发现问题出在文件名上,我正在尝试模拟一些API,它使用“control”目录创建给定路径的信号量。我只是假设路径是混合的一部分,但我想我误解了它的用途。