我试图在c中创建一个N个名为POSIX信号量的数组,但我在解除链接和关闭它们时遇到了麻烦。我需要使用一个信号量数组,因为每个信号量将代表文本文件的一段,该段稍后将进入共享内存。
我正在做一些非常类似于这篇文章,但它不工作。也许问题出在信号量的创建上?还有别的办法吗?
sem_t* semaphores[N];
for(int i = 0; i < N; i++){
char buf[100];
sprintf(buf, "s%d", i); // Give a unique name to each semaphore
semaphores[i] = sem_open(buf, O_CREAT | O_EXCL, SEM_PERMS, INITIAL_VALUE);
}
for(int i = 0; i < N; i++){
if(sem_unlink((void*)semaphores[i]) < 0){
perror("sem_unlink(0) failed OVER HERE");
exit(EXIT_FAILURE);
}
}
for(int i = 0; i < N; i++){
if(sem_close(semaphores[i]) < 0){
perror("sem_close(0) failed HERE");
exit(EXIT_FAILURE);
}
}
我得到的错误信息是:
sem_unlink(0) failed OVER HERE: No such file or directory
sem_close(3)
的参数是sem_t *
,而sem_unlink(3)
的参数是const char *
。
保留你的信号量的名字,以便以后可以传递给sem_unlink(3)
。下面的例子使用了一个结构体数组。
此外,对于sem_overview(7)
,信号量名称应该以/
开头。
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#define INITIAL_VALUE 1
#define N 8
#define SEM_PERMS 0666
int main(void)
{
struct {
char name[128];
sem_t *sem;
} semaphores[N];
for (size_t i = 0; i < N; i++) {
sprintf(semaphores[i].name, "/a-semaphore%zu", i);
semaphores[i].sem = sem_open(semaphores[i].name,
O_CREAT | O_EXCL, SEM_PERMS, INITIAL_VALUE);
if (SEM_FAILED == semaphores[i].sem)
perror(semaphores[i].name);
}
for (size_t i = 0; i < N; i++)
if (sem_unlink(semaphores[i].name) < 0)
perror(semaphores[i].name);
for (size_t i = 0; i < N; i++)
if (sem_close(semaphores[i].sem) < 0)
perror(semaphores[i].name);
}
正如John下面指出的,不一定需要存储每个名字。由于这些名称是通过算法生成的,因此当再次需要它们时,您可以从相同的模板中重新生成它们。
一个粗略的例子:
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#define INITIAL_VALUE 1
#define N 8
#define SEM_PERMS 0666
void namegen(char *dst, size_t suffix)
{
sprintf(dst, "/a-semaphore%zu", suffix);
}
int main(void)
{
sem_t *semaphores[N];
for (size_t i = 0; i < N; i++) {
char name[128];
namegen(name, i);
semaphores[i] = sem_open(name,
O_CREAT | O_EXCL, SEM_PERMS, INITIAL_VALUE);
if (SEM_FAILED == semaphores[i])
perror(name);
}
for (size_t i = 0; i < N; i++) {
char name[128];
namegen(name, i);
if (sem_unlink(name) < 0)
perror(name);
if (sem_close(semaphores[i]) < 0)
perror(name);
}
}