在C中实现互斥的问题
我正在实现一个程序来读取带有文件室名称、连接和文件室类型的文件名。例:在C中实现互斥的问题,c,multithreading,mutex,C,Multithreading,Mutex,我正在实现一个程序来读取带有文件室名称、连接和文件室类型的文件名。例: ROOM NAME: chicago CONNECTION 1: sarasota CONNECTION 2: columbus CONNECTION 3: miami CONNECTION 4: boston ROOM TYPE: END_ROOM 该程序的设计目的是向用户显示他们开始进入的房间,请求用户输入,检查输入是否是终端房间或其他连接。如果是另一个连接,将再次显示提示。如果用户到达结束房间,游戏结束。但是,我需要
ROOM NAME: chicago
CONNECTION 1: sarasota
CONNECTION 2: columbus
CONNECTION 3: miami
CONNECTION 4: boston
ROOM TYPE: END_ROOM
该程序的设计目的是向用户显示他们开始进入的房间,请求用户输入,检查输入是否是终端房间或其他连接。如果是另一个连接,将再次显示提示。如果用户到达结束房间,游戏结束。但是,我需要实现一个互斥锁,如果用户输入“time”,就会创建一个文件,将时间写入其中,并在屏幕上显示。之后,再次为用户显示提示。当去除互斥实现时,我的代码工作得很好。下面是我在代码中看到的互斥体。我似乎达到了时间功能,程序似乎识别出不正确的房间,但当输入“正确”的房间时,光标只会返回,并且什么也不做。关于我为什么只在互斥体实现中才会出现这种行为,有什么线索吗
下面是程序,您是否看到任何可能导致此问题的内容
#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//读入房间数据
//对同一目录中的rooms目录执行stat()函数
//并打开包含返回的stat结构的最新st_mtime组件的文件
#定义房间的使用数量7
char usedroms[NUM_USED_ROOMS][256];
char roomFilePath[75];
char-timeFilePath[75];
char*连接[NUM_USED_ROOMS];
int end=0;
字符输入[20];
int numberOfSteps=-1;
字符*步骤[75];
int文件描述符;
字符时间文本[100];
pthread\u mutex\u t myMutex=pthread\u mutex\u初始值设定项;
void*getTime(){
pthread_mutex_lock(&myMutex);
printf(“您询问了时间!\n”);
pthread_mutex_unlock(&myMutex);
返回NULL;
}
//检查传递的房间号是否已结束
void isEnd(int roomNumber,char*dirName){
//计算程序结束时的步骤数
numberOfSteps++;
步骤[numberOfSteps-1]=usedRooms[roomNumber];
//获取正确文件的名称
sprintf(roomFilePath,“%s/%s”,dirName,usedRooms[roomNumber]);
字符子串[20];
int numLine=1;
文件*文件指针;
filePointer=fopen(roomFilePath,“r”);
int行=0;
字符缓冲区[256];
while(fgets(buffer,sizeof(buffer),filePointer)!=NULL){
线条=线条+1;
}
fclose(文件指针);
//打开要读取的文件以查看是否为结尾。如果为结尾,请指定end=1。
filePointer=fopen(roomFilePath,“r”);
while(fgets(buffer,sizeof(buffer),filePointer)!=NULL){
if(numLine==行)
{
strcpy(子字符串,缓冲区+11);
}
numLine=numLine+1;
}
if(strstrstr(子字符串,“END”)!=NULL){
结束=1;
}
}
//获取用户输入
void getInput(){
fflush(stdin);
扫描频率(“%s”,输入);
fflush(stdin);
fflush(stdout);
}
void readFile(char*dirName){
DIR*DIR;
结构导向;
int i=0;
如果((dir=opendir(dirName))!=NULL){
/*打印目录中的所有文件和目录*/
while((ent=readdir(dir))!=NULL){
如果(strncmp(ent->d_name,“.”,sizeof(ent->d_name))=0||
strncmp(ent->d_name,“…”,sizeof(ent->d_name))==0)
{
}否则{
strcpy(使用drooms[i],ent->d_名称);
i++;
}
}
closedir(dir);
}否则{
/*无法打开目录*/
佩罗尔(“”);
}
}
void游戏(int roomNumber,char*dirName){
int i;
printf(“usedRooms是%s”,usedRooms[roomNumber]);
pthread_mutex_lock(&myMutex);
pthread\u t second thread;
pthread_create(&secondThread,NULL,getTime,NULL);
//检查用户是否猜到了末端房间
如果(结束==1){
fflush(stdout);
返回;
}
否则{
isEnd(房间号、房间名称);
如果(结束==1)
{
fflush(stdout);
返回;
}
}
int move=1;
while(move==1){
//打开传入文件室路径的文件
sprintf(roomFilePath,“%s/%s”,dirName,usedRooms[roomNumber]);
文件*文件指针;
filePointer=fopen(roomFilePath,“r”);
int fileLines=0;
字符行[256];
//计算文件中的行数,以便我知道如何遍历它
while(fgets(line,sizeof line,filePointer)!=NULL){
文件行=文件行+1;
}
fclose(文件指针);
filePointer=fopen(roomFilePath,“r”);
int currentLine=0;
//为可导航到的房间创建阵列
游戏室[6][30];;
while(fgets(line,sizeof line,filePointer)!=NULL){
char*pos;
如果((pos=strchr(第,'\n'行)!=NULL)
{
*pos='\0';
}
//打印出当前房间
如果(currentLine==0)
{
字符子串[20];
strcpy(子字符串,第+11行);
printf(“当前位置:%s\n”,子字符串);
}
//打印此房间的第一个连接
else if(currentLine==1){
printf(“可能的连接:”);
fflush(stdout);
字符子串[20];
strcpy(子字符串,第+14行);
printf(“%s”,子字符串);
fflush(stdout);
strcpy(游戏室[currentLine-1],子串);
}
//打印其余连接,逗号分隔
else if(currentLine>1&¤tLine