2015-11-25 2 views
1

Я пытаюсь решить свой школьный проект на 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, но это не имеет смысла, и я пытаюсь удалить семафор из процесса parrent, поэтому у меня должны быть привилегии для этого.IPC_RMID не работает с linux с C++

#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; 
    } 
+0

Выглядит скорее как C, чем C++, но так как вы явно задали вопрос о C++: не добавляйте тег C для вопросов C++. – Olaf

+0

Либо процессы запускаются одновременно, либо выполняются в определенном порядке. У вас не может быть обоих. – Olaf

+0

извините за мою ошибку, которую я имел в виду :) и весь мой код работает в C++, но это пример моего кода не весь мой код :) остальная часть моего кода не важна прямо сейчас – Shoxik

ответ

1

у вас есть два semid с. Один в глобальном масштабе, другой местный в main (которые тени глобального, вы должны увидеть предупреждение). createSem знает только глобальный, и инициализирует его. semctl вызывается непосредственно main , и передается локальный, который является мусором.

+0

Я этого не видел :) Большое спасибо :) – Shoxik

Смежные вопросы