gpt4 book ai didi

ipc - 使用 System V 信号量时的挑战和奇怪的经历

转载 作者:行者123 更新时间:2023-12-02 20:11:31 25 4
gpt4 key购买 nike

系统:

Linux ubuntu 3.2.0-57-generic-pae i686 GNU/Linux

问题:

我想利用信号量来实现进程原子性

下面的程序只是将一些数据写入 FIFO,而其他一些进程也尝试写入同一个 FIFO,但下面首先获取信号量的进程必须完成其写入并为其他进程释放 key

header.h

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
//#include<sys/ipc.h>
//#include<sys/sem.h>
#include<fcntl.h>
#define RES_FIFO 1234
#include<linux/sem.h>
typedef struct
{
pid_t pid;
int op1;
int op2;
char oper;
}MATH;
int result;
int ret;

流程:

#include"header.h"
int
main(void)
{
MATH request;
int fd,KK;
if(access("TEMP",F_OK)== -1)
mkfifo("TEMP",0666);
fd=open("TEMP",O_WRONLY,0666);
int i=0;
union semun a;
struct sembuf sops[2]={{0,-1,SEM_UNDO},{0,1,SEM_UNDO}};
//1.Semaphore Creation
KK=semget(RES_FIFO,1,IPC_CREAT);//semaphore set having one semaphore is created and kernel key will be returned
if(KK==-1)
{
perror("Semget Error in P1\n");
exit(1);
}
//2.Semaphore Control
a.val=1;
ret= semctl(KK,0,a);
if(ret==-1)
{
perror("SemCtl Error in P1\n");
exit(1);
}
//3.Semaphore Operations
ret=semop(KK,&sops[0],1);
if(ret==-1)
{
perror("Semop Error in decrementing at P1\n");
exit(1);
}


for(i=0;i<3;i++)
{
request.op1=i;
request.op2=i;
request.oper='+';
request.pid=getpid();
write(fd,&request,sizeof(request));
// sleep(1);
}

ret=semop(KK,&sops[1],2);
if(ret==-1)
{
perror("Semop Error in decrementing at P1\n");
exit(1);
}
return 1;
}

但问题是在信号量操作semop之后,我被卡住了,进程处于空闲状态,什么也不做,并进入休眠状态。那么我的代码有什么问题吗?

最新编辑 1:

根据相关建议,我更新了代码行

ret= semctl(KK,0,SETVAL,a);//command updated as SETVAL

并且还取消注释该行

sleep(1);

所以我的process1,process2,process3有相同的代码,这里我忘了提到从fifo读取并在控制台上打印的阅读器代码

所以我在控制台上运行这样的脚本

./reader&
./p1&
./p2&
./p3&

reader.c

#include"header.h"
void
main(void)
{
MATH request;
int fd;
int ret;
int KK;
if(access("TEMP",F_OK)== -1)
mkfifo("TEMP",0666);
fd=open("TEMP",O_RDONLY,0666);
sleep(3);
printf("Server Read Started\n");
while(1)
{
if( (ret=read(fd,&request,sizeof(request))) == -1)
{
perror("Read in Server Failed\n");
exit(1);
}
else if(ret==0)
continue;
printf("Read from PID : %d about %d %c %d \n",request.pid,request.op1,request.oper,request.op2);

}
printf("Read Complete\n");
}

根据我的目标,我希望输出是这样的

Server Read Started
Read from PID : 3673 about 0 + 0
Read from PID : 3675 about 1 + 1
Read from PID : 3674 about 2 + 2
Read from PID : 3673 about 0 - 0
Read from PID : 3675 about 1 - 1
Read from PID : 3674 about 2 - 2
Read from PID : 3673 about 0 * 0
Read from PID : 3675 about 1 * 1
Read from PID : 3674 about 2 * 2

但实际观察到的输出是这样的

Server Read Started
Read from PID : 3673 about 0 + 0
Read from PID : 3675 about 0 * 0
Read from PID : 3674 about 0 - 0
Read from PID : 3673 about 1 + 1
Read from PID : 3675 about 1 * 1
Read from PID : 3674 about 1 - 1
Read from PID : 3673 about 2 + 2
Read from PID : 3675 about 2 * 2
Read from PID : 3674 about 2 - 2

我认为我成功地清楚地解释了我的问题。任何进一步的编辑表示赞赏

最佳答案

Bug 就在代码中

//2.Semaphore Control
a.val=1;
ret= semctl(KK,0,a);
if(ret==-1)
{
perror("SemCtl Error in P1\n");
exit(1);
}

我将它放置在所有三个进程中,它们是彼此的副本,当包含相同代码的 process2 开始执行已被 process1 递减的信号量时,它再次被重新初始化,这破坏了 3 个进程的原子性

关于ipc - 使用 System V 信号量时的挑战和奇怪的经历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24566624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com