IPC_RMID 不适用于带有 C++ 的 linux
Posted
技术标签:
【中文标题】IPC_RMID 不适用于带有 C++ 的 linux【英文标题】:IPC_RMID not work on linux with C++ 【发布时间】:2015-11-25 20:16:02 【问题描述】:我正在尝试用 C++ 解决我的学校项目。我必须创建 15 个进程并且它们必须按顺序运行这意味着进程按此顺序运行 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0。它可以工作,但是当我尝试从内存中删除信号量时我从 semctl 收到错误消息。最后我使用“semctl(semid, 0, IPC_RMID, 0" 但我得到错误 22 这意味着 EINVAL 但它没有意义,我尝试从父进程中删除信号量,所以我应该有权限这样做。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
#include <sys/wait.h>
union semun
int val;
struct semid_ds *buf;
ushort *array;
;
struct sembuf sops[1];
int semid;
int wait_sem(int index, int pid)
fprintf(stderr, "\n------- Proces %d do operation wait (-1) on semaphore %d\n",pid, index);
sops[0].sem_num = index;
sops[0].sem_op = -1;
sops[0].sem_flg = 0 ;
if (semop(semid, sops, 1)<0)
perror("semop fail wait");
return 1;
else
return 0;
int signal_sem(int index, int pid)
fprintf(stderr, "\n++++++ Proces %d vykonava operaciu signal (1) na semafore %d\n",pid,index);
sops[0].sem_num = index;
sops[0].sem_op = 1;
sops[0].sem_flg = 0;
if (semop(semid, sops, 1)<0)
perror("semop fail signal");
return 1;
else
return 0;
void createSem(key_t paKey, int paSemFlg, int paNsems)
printf ("uid=%d euid=%d\n", (int) getuid (), (int) geteuid ());
(semid = semget(paKey, paNsems, paSemFlg));
for (int i = 0; i < paNsems; ++i)
semctl(semid, i, SETVAL, 0);
void kic()
printf("\naaaaaaaaaaaaaa\n");
int main()
key_t key = 1234;
int semflg = IPC_CREAT | 0666;
int nsems = 15;
int semid;
fprintf(stderr, "%d=", sops);
createSem(IPC_PRIVATE, semflg, nsems);
if (semid == -1)
perror("semget: semget failed");
return 1;
else
fprintf(stderr, "semget: semget sucess: semid = %d, parrent pid %d\n", semid, getpid());
int PROCESS_ID = 0;
pid_t PID;
for (int i = 1; i < nsems; i++)
PID = fork();
if(PID == 0)
PROCESS_ID = i;
break;
if(PID == -1)
printf("\nPID ERROR");
if(PID != 0) //parrent
printf("\n\nparrent with ID %d", PROCESS_ID);
signal_sem(PROCESS_ID+1, PROCESS_ID);
wait_sem(PROCESS_ID, PROCESS_ID);
printf ("uid=%d euid=%d\n", (int) getuid (), (int) geteuid ());
printf("\nEND %d\n", getpid());
int s;
wait(&s);
if((semctl(semid, 0, IPC_RMID, 0))==-1)
int a = errno;
printf("\nERROR IPC_RMID %d\n", a);
if(PID == 0)//child
if(wait_sem(PROCESS_ID, PROCESS_ID) == 0)
printf("\nI am child with ID %d", PROCESS_ID);
int ID_NEXT_PROCESS = 1+PROCESS_ID;
if(ID_NEXT_PROCESS == nsems)
ID_NEXT_PROCESS = 0;
signal_sem(ID_NEXT_PROCESS, PROCESS_ID);
return 0;
return 0;
【问题讨论】:
看起来更像 C 而不是 C++,但正如您明确询问的 C++:不要为 C++ 问题添加 C 标记。 进程要么同时运行,要么按特定顺序运行。你不能两者兼得。 对不起我的错误我的意思是按顺序:) 我所有的代码都在 c++ 中运行但这是我的代码示例而不是我的所有代码:) 我的其余代码现在并不重要跨度> 【参考方案1】:您有两个semid
s。一个在全局范围内,另一个在 main
本地(它会影响全局,您应该会看到警告)。 createSem
只知道全局变量,并对其进行初始化。 semctl
被main
直接调用,传给本地的,就是垃圾。
【讨论】:
以上是关于IPC_RMID 不适用于带有 C++ 的 linux的主要内容,如果未能解决你的问题,请参考以下文章
Dagger2 Qualifier 不适用于 Kotlin?
CascadeClassifier::detectMultiScale 不适用于 C++