我有这个简单的代码,我初始化系统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
有人可以解释一下为什么会发生这种情况,如果可能的话,我应该在哪里修理它?非常感谢! 差点忘了.display.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);
}
}
答案 0 :(得分:1)
这一行
semid = semget(key1,1,IPC_CREAT);
无法正确设置信号量权限。权限都为零。
根据semget
specification:
sem_perm.mode 的低位9位应设置为等于 semflg 的低位9位。
创建后,参数semflg的最低9位 定义信号量的权限(对于所有者,组和其他人) 组。这些位具有相同的格式,并且具有相同的含义 open参数的模式参数(2)(尽管执行权限不是 对信号量有意义,写权限意味着权限 改变信号量值。)
您的代码必须是这样的:
semid = semget(key1,1,IPC_CREAT | 0660 );
但是现在你的信号量可能已经存在且权限错误。