【发布时间】: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++ 中运行但这是我的代码示例而不是我的所有代码:) 我的其余代码现在并不重要跨度>