信号量在 运行 作为超级用户时工作,否则无法工作

Semaphores working when running as superuser,fail to work otherwise

我有这个简单的代码,我在其中初始化系统 V 信号量,因此我的 2 个进程打印以下代码 10 次:"abcd"。第一个进程打印 "ab" 字符串,而另一个进程打印 "cd\n" 字符串。 因此,当我以超级用户身份执行它时,一切正常,但是当我不使用 sudo 命令执行它时,我有一个意外的输出。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/sem.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<sys/wait.h>
#include "display.h"

int main(int argc,char *argv[]){

key_t key1 = 12345;
int semid;
unsigned short semval;
int  i;
int childpid;

struct sembuf wit,signal;

wit.sem_num = 0;
wit.sem_op = -1;
wit.sem_flg = SEM_UNDO;

signal.sem_num = 0;
signal.sem_op = 1;
signal.sem_flg = SEM_UNDO;

semid = semget(key1,1,IPC_CREAT);
//  printf("Allocating the semaphore: %s\n",strerror(errno));

semval = 1;
semctl(semid,0,SETVAL,semval);
//  printf("Setting semaphore value to %d: %s\n",semval,strerror(errno));

semval = semctl(semid,0,GETVAL);
//  printf("Initialized Semaphore value to %d: %s\n",semval,strerror(errno));
sleep(1);
childpid = fork();

if(childpid==0){         /*process 2 */
    for(i=0;i<10;i++){
        semop(semid,&wit,1);
        semctl(semid,0,GETVAL,&semval);
        display("cd\n");
        semop(semid,&signal,1);
    }
    semctl(semid,0,GETVAL,&semval);
    return 0;
}

for(i=0;i<10;i++){
    semop(semid,&wit,1);   /* process 1*/
    semctl(semid,0,GETVAL,&semval);
    display("ab");
    semop(semid,&signal,1);
}
semctl(semid,0,GETVAL,&semval);
sleep(1);
semctl(semid,0,IPC_RMID);
//  printf("\nSemaphore removed from the System = %s\n",strerror(errno));
return 0;
}

因此,当我使用 "sudo ./mycodehere" 命令执行我的代码时,一切顺利并且输出正确:

abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd

但是如果我正常执行,"./mycodehere"结果不一样:

acbda
bcadb
acbda
bcadb
acbda
bcadb
acbd
cd
cd
cd

有人能解释一下为什么会这样吗?如果可能的话,我应该去哪里修复它?非常感谢! 几乎forgot.Thedisplay.c个文件:

#include <stdio.h>
#include <unistd.h>
#include "display.h"

void display(char *str)
{
  char *p;
  for (p=str; *p; p++)
  {
    write(1, p, 1);
    usleep(100);
  }
}

这一行

semid = semget(key1,1,IPC_CREAT);

未能正确设置信号量权限。权限全部为零。

根据 semget specification:

The low-order 9 bits of sem_perm.mode shall be set equal to the low-order 9 bits of semflg.

根据 Linux man page:

Upon creation, the least significant 9 bits of the argument semflg define the permissions (for owner, group and others) for the semaphore set. These bits have the same format, and the same meaning, as the mode argument of open(2) (though the execute permissions are not meaningful for semaphores, and write permissions mean permission to alter semaphore values).

您的代码必须是这样的:

semid = semget(key1,1,IPC_CREAT | 0660 );

但现在您的信号量可能已经存在,但权限错误。