我正在实现使用共享内存的问题的解决方案,但不知何故,我的代码似乎在print语句和if语句之间“冻结”。
以下是相关的代码段:
#include "ch_problem_headers.h"
int main(int argc, char *argv[])
{
int semid, shmid;
int i;
int waiting_C, waiting_H = 0; // shared
int c_pid,h_pid;
time_t t;
// There should be three semaphores: S for when to pass the molecule on,
// SC for the carbon waiting, and SH for the hydrogen waitin
unsigned short seminit[NUM_SEMS];
struct common *shared;
union semun semctlarg;
srand((unsigned)time(&t));
if((semid = semget(IPC_PRIVATE, NUM_SEMS, IPC_CREAT|0777)) < 0)
{
perror("semget");
exit(EXIT_FAILURE);
}
// Initialize semaphores
seminit[S_SEM] = 1;
seminit[SC_SEM] = 0;
seminit[SH_SEM] = 0;
semctlarg.array = seminit;
// Apply initialization
if((semctl(semid, NUM_SEMS, SETALL, semctlarg)) < 0)
{
perror("semctl");
exit(EXIT_FAILURE);
}
// Get shared memory id
if((shmid = shmget(IPC_PRIVATE, 1*K, IPC_CREAT|IPC_EXCL|0660)) < 0)
{
perror("shmget");
exit(EXIT_FAILURE);
}
// Retrieve pointer to shared data structure
if((shared = (struct common *)shmat(shmid, 0, 0)) < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
}
shared->waiting_C = 0;
shared->waiting_H = 0;
printf("ready to fork\n");
// fork process C
c_pid = fork();
printf("c_pid is %d\n", c_pid);
if(c_pid == 0)
{
printf("I'm process C!/n");
// wait on S
semWait(semid, S_SEM);
// if waiting_H >= 4
if(shared->waiting_H >= 4)
{
// signal SH four times
for(i = 0; i < 4; i++)
{
semSignal(semid, SH_SEM);
printf("H");
}
// Decrement waiting_H by 4
shared->waiting_H -= 4;
// Signal S
semSignal(semid, S_SEM);
}
// Otherwise, increment waiting_C by 1
else
{
shared->waiting_C += 1;
// Signal S and wait for SC
semSignal(semid, S_SEM);
semWait(semid, SC_SEM);
}
}
else
{
printf("C's process id is %d\n", c_pid);
printf("ready to fork again\n");
// fork process H
h_pid = fork();
printf("Is h_pid zero? %d\n", (h_pid == 0));
if(h_pid == 0)
{
printf("I'm process H!/n");
// Wait on S
semWait(semid, S_SEM);
// If waiting_h >= 3
if(shared->waiting_H >= 3)
{
// Signal SH three times, decrement waiting_H by 3, signal SC, decrement
for(i = 0; i < 3; i++)
{
printf("H");
semSignal(semid, SH_SEM);
}
shared->waiting_H -=3;
semSignal(semid, SC_SEM);
shared->waiting_C -= 1;
semSignal(semid, S_SEM);
// waitng_C by 1, and signal S
}
// Otherwise, increment waiting_H by 1, signal S, and wait on SH
else
{
shared->waiting_H += 1;
semSignal(semid, S_SEM);
semWait(semid, SH_SEM);
}
}
else
{
printf("In the parent\n");
}
}
}
相关的头文件:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#define K 1024
#define NUM_SEMS 3
#define SEMKEY 77
#define SHMKEY 77
#define S_SEM 0
#define SH_SEM 1
#define SC_SEM 2
#define NUM_H 4
#define NUM_C 1
union semun
{
unsigned short *array;
};
struct common
{
int waiting_C;
int waiting_H;
};
void semWait(int semid, int semaphore)
{
struct sembuf psembuf;
psembuf.sem_op = -1;
psembuf.sem_flg = 0;
psembuf.sem_num = semaphore;
semop(semid, &psembuf, 1);
return;
}
void semSignal(int semid, int semaphore)
{
struct sembuf vsembuf;
vsembuf.sem_op = 1;
vsembuf.sem_flg = 0;
vsembuf.sem_num = semaphore;
semop(semid, &vsembuf, 1);
return;
}
运行时的程序输出如下:
父输出(正确):
准备分叉
c_pid是2977
C的流程ID是2977
准备再次分叉
h_pid是否为零? 0
在父母
中儿童输出:
h_pid是否为零? 1
c_pid为0
我尝试在valgrind中运行程序,程序在子输出后暂停。我很困惑这是如何可能的,因为程序似乎只是在c_pid print语句和if(c_pid == 0)语句之间停止。
有没有人知道为什么会这样?非常感谢。