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】:

您有两个semids。一个在全局范围内,另一个在 main 本地(它会影响全局,您应该会看到警告)。 createSem 只知道全局变量,并对其进行初始化。 semctlmain直接调用,传给本地的,就是垃圾。

【讨论】:

以上是关于IPC_RMID 不适用于带有 C++ 的 linux的主要内容,如果未能解决你的问题,请参考以下文章

为啥相同的语句不适用于 C++ 中的类成员?

Dagger2 Qualifier 不适用于 Kotlin?

CascadeClassifier::detectMultiScale 不适用于 C++

带有 RemoteViews 的 setBackgroundResource 不适用于布局

VSCode/MinGW 智能感知不适用于 C++

溢出:隐藏;不适用于带有 IFRAME 的 Chrome?