gpt4 book ai didi

c - 在 C 中实现互斥体的问题

转载 作者:行者123 更新时间:2023-11-30 16:45:58 24 4
gpt4 key购买 nike

我正在实现一个程序来读取包含房间名称、连接和房间类型的文件名。例如:

ROOM NAME: chicago
CONNECTION 1: sarasota
CONNECTION 2: columbus
CONNECTION 3: miami
CONNECTION 4: boston
ROOM TYPE: END_ROOM

该程序旨在向用户显示他们开始的房间,要求用户输入,检查输入是否是结束房间或其他连接。如果是其他连接,则会再次显示提示。如果用户到达最后的房间,游戏就结束。但是,我需要实现一个互斥锁,如果用户输入“时间”,则会创建一个文件,将时间写入其中,并将其显示在屏幕上。之后,再次向用户显示提示。当互斥锁实现被删除时,我的代码工作正常。这是当互斥体位于代码中时我所看到的。我似乎达到了时间功能,程序似乎识别出了不正确的房间,但是当输入“正确”的房间时,光标只是返回并且不执行任何操作。关于为什么我只在互斥实现上出现这种行为的任何线索?

enter image description here

程序如下,您是否发现任何可能导致此问题的内容?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>

//Read in the room data
//Perform the stat() function on the rooms directory in the same directory
//and open the file with the most recent st_mtime component of the returned stat struct

#define NUM_USED_ROOMS 7

char usedRooms[NUM_USED_ROOMS][256];
char roomFilePath[75];
char timeFilePath[75];
char* connections[NUM_USED_ROOMS];
int end = 0;
char input[20];
int numberOfSteps = -1;
char *steps[75];
int file_descriptor;
char timeText[100];
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;


void * getTime() {
pthread_mutex_lock(&myMutex);
printf("You asked for the time!\n");
pthread_mutex_unlock(&myMutex);
return NULL;
}

//Check if the room number passed is the end
void isEnd(int roomNumber, char *dirName){

//Counting the number of steps for the end of the program
numberOfSteps++;
steps[numberOfSteps - 1] = usedRooms[roomNumber];

//Getting the name of the proper file
sprintf(roomFilePath, "%s/%s", dirName, usedRooms[roomNumber]);
char substring[20];
int numLine = 1;

FILE * filePointer;
filePointer = fopen(roomFilePath, "r");
int lines = 0;
char buffer[256];
while(fgets(buffer, sizeof(buffer), filePointer) != NULL){
lines = lines + 1;
}

fclose(filePointer);

//Opening the file to read to see if it is the end. If it is, assign end = 1.
filePointer = fopen(roomFilePath, "r");
while(fgets(buffer, sizeof(buffer), filePointer) != NULL) {

if (numLine == lines)
{
strcpy(substring, buffer+11);
}
numLine = numLine + 1;
}

if(strstr(substring, "END" ) != NULL) {
end = 1;
}
}

//Get the user input
void getInput() {

fflush(stdin);
scanf("%s", input);
fflush(stdin);
fflush(stdout);
}

void readFile(char *dirName){

DIR *dir;
struct dirent *ent;
int i = 0;
if ((dir = opendir (dirName)) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
if (strncmp(ent->d_name,".",sizeof(ent->d_name)) == 0 ||
strncmp(ent->d_name,"..",sizeof(ent->d_name)) == 0 )
{

} else {
strcpy(usedRooms[i],ent->d_name);
i++;
}

}
closedir (dir);
} else {
/* could not open directory */
perror ("");
}

}

void playGame(int roomNumber, char * dirName){

int i;
printf("usedRooms is %s", usedRooms[roomNumber]);
pthread_mutex_lock(&myMutex);
pthread_t secondThread;
pthread_create(&secondThread, NULL, getTime,NULL);


//Check if the user guessed the end room
if(end == 1) {

fflush(stdout);
return;
}

else{

isEnd(roomNumber, dirName);
if (end == 1)
{
fflush(stdout);
return;
}

}

int move = 1;
while(move == 1) {

//Open the file of the path of the room passed in
sprintf(roomFilePath, "%s/%s", dirName, usedRooms[roomNumber]);
FILE * filePointer;
filePointer = fopen(roomFilePath, "r");
int fileLines = 0;
char line[256];

//Count the lines in the file so I know how to traverse it
while(fgets(line, sizeof line, filePointer) != NULL) {

fileLines = fileLines + 1;
}

fclose(filePointer);

filePointer = fopen(roomFilePath, "r");

int currentLine = 0;


//Create the array for the rooms that can be navigated to
char gameRooms[6][30];

while(fgets(line, sizeof line, filePointer) != NULL) {
char *pos;
if((pos = strchr(line, '\n')) != NULL)
{
*pos = '\0';
}

//Print out the current room
if (currentLine == 0)
{
char substring[20];
strcpy(substring, line+11);
printf("CURRENT LOCATION: %s\n", substring);
}
//Print the first connection from this room
else if (currentLine == 1){

printf("POSSIBLE CONNECTIONS: ");
fflush(stdout);
char substring[20];
strcpy(substring, line+14);
printf("%s", substring);
fflush(stdout);
strcpy(gameRooms[currentLine - 1], substring);

}
//Print the rest of the connections, comma separated
else if (currentLine > 1 && currentLine < fileLines - 1) {
printf(",");
fflush(stdout);
char substring[20];
strcpy(substring, line+14);
printf("%s", substring);
fflush(stdout);
strcpy(gameRooms[currentLine - 1], substring);
//gameRooms[currentLine - 1] = substring;

}
else {

printf(".");
fflush(stdout);
}

currentLine = currentLine + 1;
}
fclose(filePointer);

printf("\nWHERE TO?>");

//Get the user input
getInput();

if(strcmp("time", input) == 0){
pthread_mutex_unlock(&myMutex);
pthread_join(secondThread, NULL);
pthread_mutex_lock(&myMutex);
pthread_create(&secondThread, NULL, getTime, NULL);
}

//Loop through the file to see if the input matches a room name in the array
for(i = 0; i < fileLines - 2; i++) {

if (strcmp(gameRooms[i], input) == 0)
{
int j;
for(j = 0; j < NUM_USED_ROOMS; j++) {

//If there is a match, play the game starting at the room entered
if(strcmp(usedRooms[j], input) == 0) {
printf("THE STRINGS MATCH usedRooms is %s "
"and input is %s\n",usedRooms[j],input);
playGame(j,dirName);
}
}
move = 0;
}
}
//If the user's input didn't match the list of rooms
if (move == 1) {

printf("\nHUH? I DON'T UNDERSTAND THAT ROOM. TRY AGAIN. \n\n");
fflush(stdout);
fflush(stdin);
}

}


}


int main() {


int newestDirTime = -1; // Modified timestamp of newest subdir examined
char targetDirPrefix[32] = "walterer.rooms."; // Prefix we're looking for
char newestDirName[256]; // Holds the name of the newest dir that contains prefix
memset(newestDirName, '\0', sizeof(newestDirName));

DIR* dirToCheck; // Holds the directory we're starting in
struct dirent *fileInDir; // Holds the current subdir of the starting dir
struct stat dirAttributes; // Holds information we've gained about subdir

dirToCheck = opendir("."); // Open up the directory this program was run in

if (dirToCheck > 0) // Make sure the current directory could be opened
{
while ((fileInDir = readdir(dirToCheck)) != NULL) // Check each entry in dir
{
if (strstr(fileInDir->d_name, targetDirPrefix) != NULL) // If entry has prefix
{
//printf("Found the prefex: %s\n", fileInDir->d_name);
stat(fileInDir->d_name, &dirAttributes); // Get attributes of the entry

if ((int)dirAttributes.st_mtime > newestDirTime) // If this time is bigger
{
newestDirTime = (int)dirAttributes.st_mtime;
memset(newestDirName, '\0', sizeof(newestDirName));
strcpy(newestDirName, fileInDir->d_name);
}
}
}
}

closedir(dirToCheck);

//Read the file at the specified directory
readFile(newestDirName);

int start;
int i;
for (i = 0; i < NUM_USED_ROOMS; i++)
{
memset(roomFilePath, '\0', sizeof(roomFilePath));
sprintf(roomFilePath,"%s/%s", newestDirName, usedRooms[i]);
char output[256];
memset(output, '\0', sizeof(output));
char* token;
char* connectRoom;

FILE *filePointer;
filePointer = fopen(roomFilePath,"r");

//Find the starting room and pass that into the playGame function
if (filePointer == NULL)
{
printf("Unable to open file!\n");
} else {
while(!feof(filePointer)) {

fgets(output, 256, filePointer);
token = strtok(output, "\n");

if(strstr(token, "START") != NULL){
start = i;
}
}
fclose(filePointer);
}
}

//Play the game with the starting room at the directory name
playGame(start, newestDirName);

printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS: \n", numberOfSteps);
for(i = 0; i < numberOfSteps; i++){

printf("%s\n", steps[i]);
}
return 0;
}

最佳答案

通常,您应该尽可能短地锁定互斥体。违反此规则是一种严重的反模式,称为“自找麻烦”,通常会受到僵局的惩罚。从代码中删除该反模式。

关于c - 在 C 中实现互斥体的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43928614/

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