我试图在while循环中使用信号量,并且我的程序在无限循环中运行。基本上,我派生孩子并使用execv启动新的用户进程。进程使用共享内存中的信号量进行通信。
struct shared
{
int count;
sem_t sem;
} *shmem;
void forking()
{
key_t shmkey = ftok("makefile",777);
if (shmkey == -1) {
perror("Ftok failed");
exit(-1);
}
// Get our shm id
shmid = shmget(shmkey, sizeof(shared), 0666 | IPC_CREAT);
if (shmid == -1) {
perror("Failed to allocate shared memory region");
exit(-1);
}
// Attach to our shared memory
shmem = (shared*)shmat(shmid, (void *)0, 0);
if (shmem == (void *)-1) {
perror("Failed to attach to shared memory region");
exit(-1);
}
sem_init(&(shmem->sem),1,1);
pid_t PID;
int i;
for(i=0;i<4;i++)
{
PID=fork();
if(PID==0)
{
static char *args[]={"./child",NULL};
int status;
if(( status= (execv(args[0], args)))==-1)
perror("failed to execv");
exit(EXIT_FAILURE);
}
if(PID>0)
{
while(1)
{
sem_wait(&(shmem->sem));
{
shmem->count=shmem->count+1;
}
sem_post(&(shmem->sem));
}
}
if(PID<0)
perror("error in fork");
}
}
main()
{
forking();
}
在child.c
struct shared
{
int count;
sem_t sem;
} shmem;
void main()
{
bool alive=true;
do
{
sem_wait(&(shmem->sem));
if(shmem->count==5)
{
shmem->count=0;
alive=false;
}
sem_post(&(shmem->sem));
}while(alive);
}
child.c无休止地循环,而不允许父级将i递增到5。即使我在第一个文件中的while循环中注释掉并且只是让它递增而没有循环,也会发生这种情况。
答案 0 :(得分:1)
您使用的fork错误,并且绝对不使用共享内存。
这里有几点
要使代码正常工作,您应该使用 pthread_*
,因为它将存在于相同的内存空间中,并使全局变量具有可变性,因为gcc会尝试优化并具有这样做会产生奇怪的行为。
好吧,我似乎已经错失了很多要点,但我的假设并没有完全错。
所以您的child.c缺少很多代码
execve
,则实际上会丢失以前在父级进程中映射的所有内存映射。shmem->count
永远不会真正等于5,您将不得不在某些时候中断或更改子代码中的条件。 这就是你的孩子的样子。
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct
{
int count;
sem_t sem;
} shared;
shared *shmem;
int shmid;
key_t shmkey;
int main()
{
int alive=1;
shmkey = ftok("makefile",777);
if (shmkey == -1) {
perror("Ftok failed");
exit(-1);
}
// Get our shm id
shmid = shmget(shmkey, sizeof *shmem, 0);
if (shmid == -1) {
perror("Failed to allocate shared memory region");
exit(-1);
}
// Attach to our shared memory
shmem = (shared*)shmat(shmid, (void *)0, 0);
if (shmem == (shared *)-1) {
perror("Failed to attach to shared memory region");
exit(-1);
}
do
{
sem_wait(&(shmem->sem));
printf("%d\n", shmem->count);
if(shmem->count > 5)
{
shmem->count=0;
alive=0;
}
sem_post(&(shmem->sem));
}while(alive);
printf("I have finished %u\n", getpid());
exit(0);
}