So, my 上一篇文章 https://stackoverflow.com/questions/26321100/concept-any-good-c-example-of-fork-pipe-where-one-parent-creates-multiple被标记为偏离主题、过于模糊,并寻求有用代码的意见和建议。它做了这些事情,所以我重新发布作为我正在处理的代码的问题。感谢上一篇文章中的那些人,我能够通过回顾你们所说的内容来拼凑出我所拥有的内容。
这里的重点是父/子关系以及使用 fork() 和 pipeline() 来获得所需的效果。
该项目是一个 POSIX 纸牌游戏,其中父级(发牌者)使用父级自己的管道将其分叉为 5 个子级(玩家)。家长向玩家发牌(每人至少 5 张牌),直到一名玩家拿到 3 张相同的牌(不弃牌)。获胜的孩子将获胜的手牌和 EOF (exit(0)) 发送给父母以宣布胜利。这会触发父级打印获胜玩家并将 EOF 传输给剩余的子级以将其关闭(exit(1))。然后父级关闭。如果父级到达牌堆末尾而没有获胜者,则会将 EOF 传输给子级,等待它们退出 (1)...然后关闭。
我遇到的主要问题是子程序如何单独读取每张卡,而不是一遍又一遍地从管道读取相同的值。我想我缺少一种同步父级写入管道和子级从管道读取的方法。
我对这些人来说是完全陌生的,所以非常感谢任何帮助。非常感谢。
代码更新:(编译时有很多问题)完成并编译,但我显然在管道和通过它们中继数据方面遇到了麻烦。这里有很多错误,从无法玩游戏,到无法读取或写入管道,再到留下僵尸进程。如果您对我的混乱有任何意见,我将不胜感激。哈哈
这是我运行程序(play.c)时的输出:
os@debian:~/Documents/cpsc351/projects/assn2$ gcc -o play play.c
os@debian:~/Documents/cpsc351/projects/assn2$ ./play
Pipe Success...toChild 1 created.
Pipe Success...toParent 1 created.
Pipe Success...toChild 2 created.
Pipe Success...toParent 2 created.
Pipe Success...toChild 3 created.
Pipe Success...toParent 3 created.
Pipe Success...toChild 4 created.
Pipe Success...toParent 4 created.
Pipe Success...toChild 5 created.
Pipe Success...toParent 5 created.
Parent: All players are at the table. Dealing cards...
30 5C to player 1
51 KS to player 2
9 10H to player 3
25 KD to player 4
6 7H to player 5
18 6D to player 1
45 7S to player 2
29 4C to player 3
37 QC to player 4
12 KH to player 5
7 8H to player 1
19 7D to player 2
20 8D to player 3
49 JS to player 4
35 10C to player 5
15 3D to player 1
5 6H to player 2
36 JC to player 3
0 AH to player 4
22 10D to player 5
48 10S to player 1
27 2C to player 2
42 4S to player 3
16 4D to player 4
32 7C to player 5
4 5H to player 1
14 2D to player 2
41 3S to player 3
39 AS to player 4
1 2H to player 5
26 AC to player 1
46 8S to player 2
34 9C to player 3
11 QH to player 4
24 QD to player 5
17 5D to player 1
31 6C to player 2
44 6S to player 3
40 2S to player 4
3 4H to player 5
21 9D to player 1
50 QS to player 2
13 AD to player 3
33 8C to player 4
23 JD to player 5
43 5S to player 1
2 3H to player 2
28 3C to player 3
47 9S to player 4
38 KC to player 5
10 JH to player 1
8 9H to player 2
Child: Fork Success...Player 4 is sitting at the table.
Child: Player 4 is dealt a KD. Hand Total = 1 cards.
Child: Player 4 is dealt a QC. Hand Total = 2 cards.
Child: Player 4 is dealt a JS. Hand Total = 3 cards.
Child: Player 4 is dealt a AH. Hand Total = 4 cards.
Child: Player 4 is dealt a 4D. Hand Total = 5 cards.
Child: Player 4 is dealt a AS. Hand Total = 6 cards.
Child: Player 4 is dealt a QH. Hand Total = 7 cards.
Child: Player 4 is dealt a 2S. Hand Total = 8 cards.
Child: Player 4 is dealt a 8C. Hand Total = 9 cards.
Child: Player 4 is dealt a 9S. Hand Total = 10 cards.
Child: Fork Success...Player 5 is sitting at the table.
Child: Player 5 is dealt a 7H. Hand Total = 1 cards.
Child: Player 5 is dealt a KH. Hand Total = 2 cards.
Child: Player 5 is dealt a 10C. Hand Total = 3 cards.
Child: Player 5 is dealt a 10D. Hand Total = 4 cards.
Child: Player 5 is dealt a 7C. Hand Total = 5 cards.
Child: Player 5 is dealt a 2H. Hand Total = 6 cards.
Child: Player 5 is dealt a QD. Hand Total = 7 cards.
Child: Player 5 is dealt a 4H. Hand Total = 8 cards.
Child: Player 5 is dealt a JD. Hand Total = 9 cards.
Child: Player 5 is dealt a KC. Hand Total = 10 cards.
Child: Player 5 has left the table.
os@debian:~/Documents/cpsc351/projects/assn2$ Child: Player 4 has left the table.
Child: Fork Success...Player 3 is sitting at the table.
Child: Player 3 is dealt a 10H. Hand Total = 1 cards.
Child: Player 3 is dealt a 4C. Hand Total = 2 cards.
Child: Player 3 is dealt a 8D. Hand Total = 3 cards.
Child: Player 3 is dealt a JC. Hand Total = 4 cards.
Child: Player 3 is dealt a 4S. Hand Total = 5 cards.
Child: Player 3 is dealt a 3S. Hand Total = 6 cards.
Child: Player 3 is dealt a 9C. Hand Total = 7 cards.
Child: Player 3 is dealt a 6S. Hand Total = 8 cards.
Child: Player 3 is dealt a AD. Hand Total = 9 cards.
Child: Player 3 is dealt a 3C. Hand Total = 10 cards.
Child: Player 3 has left the table.
Child: Fork Success...Player 2 is sitting at the table.
Child: Player 2 is dealt a KS. Hand Total = 1 cards.
Child: Player 2 is dealt a 7S. Hand Total = 2 cards.
Child: Player 2 is dealt a 7D. Hand Total = 3 cards.
Child: Player 2 is dealt a 6H. Hand Total = 4 cards.
Child: Player 2 is dealt a 2C. Hand Total = 5 cards.
Child: Player 2 is dealt a 2D. Hand Total = 6 cards.
Child: Player 2 is dealt a 8S. Hand Total = 7 cards.
Child: Player 2 is dealt a 6C. Hand Total = 8 cards.
Child: Player 2 is dealt a QS. Hand Total = 9 cards.
Child: Player 2 is dealt a 3H. Hand Total = 10 cards.
Child: Player 2 is dealt a 9H. Hand Total = 11 cards.
Child: Player 2 has left the table.
Child: Fork Success...Player 1 is sitting at the table.
Child: Player 1 is dealt a 5C. Hand Total = 1 cards.
Child: Player 1 is dealt a 6D. Hand Total = 2 cards.
Child: Player 1 is dealt a 8H. Hand Total = 3 cards.
Child: Player 1 is dealt a 3D. Hand Total = 4 cards.
Child: Player 1 is dealt a 10S. Hand Total = 5 cards.
Child: Player 1 is dealt a 5H. Hand Total = 6 cards.
Child: Player 1 is dealt a AC. Hand Total = 7 cards.
Child: Player 1 is dealt a 5D. Hand Total = 8 cards.
Child: Player 1 has at least "3 of a Kind". Hand Total = 8 cards.
当前代码:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "cards.h"
#include "cards.c"
#define READ 0
#define WRITE 1
#define PLAYERS 5
int main(int argc, char *argv[])
{
//loop declarations ***Would not let me initialize within a for-loop...c99 error.***
int i;
int j;
pid_t player[PLAYERS];
int toChild_pipe[PLAYERS][2];
int toParent_pipe[PLAYERS][2];
int dealt_card;
int card_count = 1;
int player_count = 0;
int status_forChild;
int status_forParent;
int player_card;
for(i = 0; i < PLAYERS; i++)
{
// Create the pipes
if (pipe(toChild_pipe[i]) < 0)
{
perror("'To-Child' Pipe Error\n");
exit(1);
}
if (pipe(toParent_pipe[i]) < 0)
{
perror("'To-Parent' Pipe Error\n");
exit(1);
}
// Fork the child (new player)
player[i] = fork();
if (player[i] < 0)
{
perror("Fork Error:");
printf(" Player %d cloud not sit at table.\n", i+1);
exit(1);
}
else if (player[i] > 0) //Parent Process
{
// Close unsed pipe ends in Parent
close(toChild_pipe[i][READ]);
close(toParent_pipe[i][WRITE]);
}
else //(player[i] == 0)-- Child Process
{
int player_num = (i+1);
int player_card;
int hand[13] = {0};
int player_card_count = 0;
bool game_over = false;
printf("Child: Fork Success...Player %d is sitting at the table.\n", player_num);
// Close unsed pipe ends in Parent
close(toParent_pipe[i][READ]);
close(toChild_pipe[i][WRITE]);
while(!game_over)
{
if ((status_forChild = read(toChild_pipe[i][READ], &player_card, sizeof(player_card))) == 0)
{
//EOF from parent. Player lost.
game_over = true;
close(toParent_pipe[i][WRITE]);
close(toChild_pipe[i][READ]);
printf("Child: Player %d has left the table.\n", player_num);
exit(1);
}
else if (status_forChild == -1)
{
perror("");
printf("Child %d: ERROR: Could not read from pipe.\n", i+1);
exit(1);
}
else
{
//Players have 5 cards, loop through hand to check for winner. If yes, WIN.
if (player_card_count == 5)
{
for (j = 0; j < 13; j++)
{
if(hand[j] >=3)
{
//WINNER! Close process (status = 0)
printf("Child: Player %d has at least. Hand Total = %d cards.\n"
, player_num, rank(player_card));
close(toParent_pipe[i][WRITE]);
close(toChild_pipe[i][READ]);
exit(0);
}
}
}
//Read the current card value dealt, increment card value in hand array
int card_index = value_index(rank(player_card));
hand[card_index]++;
player_card_count++;
printf("Child: Player %d is dealt a %s%s. Hand Total = %d cards.\n", player_num, rank(player_card),
suit(player_card), player_card_count);
if ((hand[card_index] >= 3)&&(player_card_count > 5)) //at least (3 of a kind) and (> 5 card hand)
{
//WINNER! Close process (status = 0)
printf("Child: Player %d has at least. Hand Total = %d cards.\n", player_num, rank(player_card));
close(toParent_pipe[i][WRITE]);
close(toChild_pipe[i][READ]);
exit(0);
}
}
}
}
}
shuffle();
printf("Parent: All players are at the table. Dealing cards... \n");
while ((dealt_card = deal()) != EOF)
{
//Card is written to the pipe for current player
if ((status_forParent = write(toChild_pipe[i][WRITE], &dealt_card, sizeof(dealt_card))) == -1)
{
perror("");
printf("Parent: ERROR: Could not read from pipe for Child %d.\n", i+1);
exit(1);
}
//If child process exited with status = 0, child had 3 of a kind and wins game.
else if (status_forParent == 0)
{
printf("Parent: Player %d has WON!!!\n", player_count+1, rank(player_card));
break;
}
else
{
printf(" %d %s%s to player %d\n", dealt_card, rank(dealt_card), suit(dealt_card), player_count+1);
if (player_count >= PLAYERS-1)
player_count = 0;
else
player_count++;
}
}
// Close pipe ends
close(toParent_pipe[i][READ]);
close(toChild_pipe[i][WRITE]);
wait(NULL);
return 0;
}