为了账号安全,请及时绑定邮箱和手机立即绑定

使用 JNA 发送到 POSIX 信号量

使用 JNA 发送到 POSIX 信号量

慕少森 2023-03-17 15:27:00
我正在尝试在 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;  }}
查看完整描述

1 回答

?
www说

TA贡献1775条经验 获得超8个赞

我最初也不能让它与 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);

}

这是一个使用 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)));

        }

    }

}


查看完整回答
反对 回复 2023-03-17
  • 1 回答
  • 0 关注
  • 67 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信