[英]Linux fork,semaphore,pipe with C
因此,我試圖了解叉子的信號燈。 我編寫了一個C程序,該程序分叉一次並通過管道從子pid到父pid傳遞一個整數4次。 因此,我已經能夠使用分叉的孩子之間的管道成功讀取/寫入。 但是,當我嘗試循環多次寫入管道時,我遇到了問題。 我試圖用信號量來調節我的管道,以便獲得交替的寫入,讀取,寫入,讀取等。我的帶有信號量的代碼現在生成SEGFAULTS或只是在打印出我的標頭之后掛起。 我知道我可以用另一個管道來完成此規則,但是我專門這樣做是為了更好地理解信號量。 我一直在讀一本OS書籍,但並不是真正的點擊。 誰能通過我的代碼示例向我解釋這一點? (這不是家庭作業)
/*****PROTOTYPES*****/
int SpawnBots();
void sender(int fd[2], sem_t *sem);
void receiver(int fd[2], sem_t *sem);
int exp(int base, int exponent);
int main(int argc, char *argv[]) {
printf("WELCOME...\n");
SpawnBots();
return 0;
}
int SpawnBots() {
sem_t *sem = sem_open("test_semaphore", O_CREAT | O_EXCL, 1, 1);
sem_unlink("test_semaphore");
int fd[2]; //0=input 1=output
pid_t pid;
//sem_init(sem, 1, 1);
pipe(fd);
pid = fork();
if(pid==0) {
//pid=0 is child
sender(fd, sem);
} else {
//pid!=0 is parent
receiver(fd, sem);
}
return 0;
}
void sender(int fd[2], sem_t *sem) {
//child closes read pipe
fflush(stdout);
close(fd[0]);
int val;
char buffer[32];
//writes 4 numbers to stdout
for(int i=1; i<=4; i++) {
sem_wait(sem); //takes control; waits for read from receiver()
val = exp((i+3), i);
printf("\tChild %d: \t%d\n", i, val); //prints out current data its writing
sprintf(buffer, "%d", val);
write(fd[1], buffer, strlen(buffer) + 1); //writes to stdout
sem_post(sem); //hands back control
}
close(fd[1]);
sem_close(sem);
exit(0);
}
void receiver(int fd[2], sem_t *sem) {
//child closes write pipe
//fflush(stdout);
close(fd[1]);
int val;
int i=1;
int nbytes=1;
char buffer[32];
//reads in numbers until stdout is empty
while(1) {
sem_wait(sem); //takes control; waits for write from sender()
if((nbytes = read(fd[0], buffer, sizeof(buffer)+1)) > 0) { //reads from stdout
val = atoi(buffer);
printf("\tParent %d: \t%d\n", i, val); //prints out current data its reading
i++;
} else {
break;
}
sem_post(sem); //hands back control
}
sem_post(sem);
close(fd[0]);
sem_close(sem);
exit(0);
}
int exp(int base, int exponent) {
int output = 1;
for(int i=1; i<=exponent; i++) {
output = output * base;
}
return output;
}
父進程和子進程sem_wait
針對該值為1
信號量爭用sem_wait
。 如果父母獲勝,則會阻止其進行read
通話。 而孩子在sem_wait
仍然處於阻塞sem_wait
。 這是一個僵局。
解決此死鎖的一種方法是創建值為2
的信號量。
另一種方法是從receiver
刪除sem_wait(sem)
,從sender
刪除sem_post(sem)
。 這是因為receiver
sender
無論如何都會阻止read
,直到sender
將某些內容寫入管道為止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.