gpt4 book ai didi

java - 使用 JNA 发布到 POSIX 信号量

转载 作者:行者123 更新时间:2023-11-30 05:34:06 25 4
gpt4 key购买 nike

我正在尝试在 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);
}

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

关于java - 使用 JNA 发布到 POSIX 信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56954544/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com