我是c ++初学者,正在编写#include "mazesolver.h"
int main()
{
// Elapsed Time
time(&startTime);
// Start Process
if (start() == EXIT_FAILURE)
{
return EXIT_FAILURE;
}
// Create Threads
if (create() == EXIT_FAILURE)
{
return EXIT_FAILURE;
}
// Explore the Map
explore();
// End the Process
if (end() == EXIT_FAILURE)
{
return EXIT_FAILURE;
}
// Return Success
return EXIT_SUCCESS;
}
int start()
{
string tempData;
// Create File if not Found
fstream file(fileName.c_str(), ios::in);
// If file not found create new file
if (!file)
{
fstream createFile(fileName.c_str(), ios::out);
createFile.close();
return EXIT_FAILURE;
}
// If file contents are empty
else if(file.peek() == file.eof())
{
cout << "-- File Contains No Data --\n\n";
return EXIT_FAILURE;
}
// Allocate memory
AllocateProgramsVariableMemory();
// Load the Maze Obj
mazeObj->LoadMaze(fileName);
// Create new instance of the maze
Maze * mazeSoln = new Assignm3::Maze(mazeObj->getLength(), mazeObj->getBreadth(), mazeObj->getStartLocation(), mazeObj->getEndLocation());
// Discovered Solution Path
discoveredASolutionPath = false;
// Get necesssary data from global finder resource
// for maze and initialize as 0 as it is the
// start of the process
globalPathFinderResource.usedThreadNameIndex = 0;
globalPathFinderResource.noOfDeadEndPathsFound = 0;
globalPathFinderResource.noOfBarriersDiscovered = 0;
globalPathFinderResource.noOfDangerAreaDiscovered = 0;
// Initialize neessary data to 0
activeThreads = 0;
submittedPaths = 0;
numSoln = 0;
return EXIT_SUCCESS;
}
int create()
{
while (discoveredASolutionPath == false)
{
if (areThreadsActive[2] == false && activeThreads > 0)
{
if (pthread_create(&globalPathFinderResource.activeThreadArray[2], NULL, display, NULL) != 0)
{
return EXIT_FAILURE;
}
else
{
areThreadsActive[2] = true;
}
}
if (activeThreads < (MAX_NO_OF_THREADS-1))
{
for (int i = 0; i < (MAX_NO_OF_THREADS-1); i++)
{
if (areThreadsActive[i] == false)
{
PathFinderParameterInfo threadData;
threadData.threadName = THREAD_NAMES[globalPathFinderResource.usedThreadNameIndex % 63];
threadData.threadIDArrayIndex = i;
globalPathFinderResource.activeThreadParamArray[i] = &threadData;
if (pthread_create(&globalPathFinderResource.activeThreadArray[i], NULL, findPath, (void *) &threadData) != 0)
{
return EXIT_FAILURE;
}
else
{
areThreadsActive[i] = true;
globalPathFinderResource.usedThreadNameIndex++;
activeThreads++;
// Block Out
pthread_mutex_lock(&thread_mutex);
cout << "Thread '" << threadData.threadName << "' has been created!\n\n";
// Unlock
pthread_mutex_unlock(&thread_mutex);
}
}
}
}
}
return EXIT_SUCCESS;
}
void explore()
{
// Suspend execution for 4 seconds
usleep(4000000);
// Block Out
pthread_mutex_lock(&thread_mutex);
cout << "Finished Finding a SAFE PATH!\n";
cout << "Printing Submitted maze solution:\n\n";
// Print and save accordingly
submitMazeSolnObj->printSubmittedSolution(studentName, studentID);
submitMazeSolnObj->saveSubmittedSolution(studentName, studentID);
statistics();
// Unlock
pthread_mutex_unlock(&thread_mutex);
}
int end()
{
// If there are any threads still active
// return a failure
for (int i = 0; i < MAX_NO_OF_THREADS; i++)
{
if (pthread_join(globalPathFinderResource.activeThreadArray[i], NULL) != 0)
{
return EXIT_FAILURE;
}
}
DeallocateProgramsVariableMemory();
return EXIT_SUCCESS;
}
void * findPath(void * tempData)
{
PathFinderParameterInfo threadData = *((PathFinderParameterInfo *) tempData);
// Get the location of map
Point startLocation = mazeObj->getStartLocation();
Point endLocation = mazeObj->getEndLocation();
// Assign start location
threadData.currentLocation = startLocation;
//
VectorOfPointStructType taken;
VectorOfPointStructType checked;
// Put into data
taken.push_back(threadData.currentLocation);
do
{
if (discoveredASolutionPath)
{
areThreadsActive[threadData.threadIDArrayIndex] = false;
activeThreads--;
pthread_exit(NULL);
}
Point up(threadData.currentLocation.x, threadData.currentLocation.y + 1);
Point down(threadData.currentLocation.x, threadData.currentLocation.y+ - 1);
Point left(threadData.currentLocation.x - 1, threadData.currentLocation.y);
Point right(threadData.currentLocation.x + 1, threadData.currentLocation.y);
srand(time(NULL));
string random = "0123";
// Randomize the 4 actions
for (int i = 0; i < 4; i++)
{
int x = (rand () % random.size());
char y = random[x];
random.erase(remove(random.begin(), random.end(), y), random.end());
int temp;
if (threadData.threadIDArrayIndex == 0)
{
temp = i;
}
else
{
temp = y - '0';
}
// Do actions
switch(temp)
{
case 0:
checked.push_back(up);
break;
case 1:
checked.push_back(down);
break;
case 2:
checked.push_back(left);
break;
case 3:
checked.push_back(right);
break;
}
}
int counter = 0;
if (mazeObj->IsThereBarrier(up) || mazeSolution->IsThereDanger(up))
{
counter++;
}
if (mazeObj->IsThereBarrier(down) || mazeSolution->IsThereDanger(down))
{
counter++;
}
if (mazeObj->IsThereBarrier(left) || mazeSolution->IsThereDanger(left))
{
counter++;
}
if (mazeObj->IsThereBarrier(right) || mazeSolution->IsThereDanger(right))
{
counter++;
}
if (counter == 3)
{
// Block Out
pthread_mutex_lock(&thread_mutex);
// Show where did it hit a dead end
cout << "Thread '" << threadData.threadName << "' hits a Dead End near ";
threadData.currentLocation.display(cout);
cout << ".\n";
globalPathFinderResource.noOfDeadEndPathsFound++;
pthread_mutex_unlock(&thread_mutex);
}
int backtrack = checked.size() + 1;
threadData.currentLocation = checked[backtrack];
checked.pop_back();
int counter2 = 0;
while (mazeObj->IsThereBarrier(threadData.currentLocation) || pathObj->isLocationInPath(threadData.currentLocation, taken) || mazeSolution->IsThereDanger(threadData.currentLocation) || hitBoundary(threadData.currentLocation))
{
if (checked.size() < 1)
{
areThreadsActive[threadData.threadIDArrayIndex] = false;
activeThreads--;
pthread_exit(NULL);
}
if (mazeObj->IsThereBarrier(threadData.currentLocation))
{
// Block Out
pthread_mutex_lock(&thread_mutex);
addBarrier(threadData.currentLocation, taken);
// Unlock
pthread_mutex_unlock(&thread_mutex);
}
// Return the last location
threadData.currentLocation = checked.back();
checked.push_back(threadData.currentLocation);
counter2++;
}
if (mazeObj->IsThereDanger(threadData.currentLocation))
{
// Block Out
pthread_mutex_lock(&thread_mutex);
cout << "Thread '" << threadData.threadName << "' stepped into Danger at ";
threadData.currentLocation.display(cout);
cout << ".\n";
addDanger(threadData.currentLocation, taken);
areThreadsActive[threadData.threadIDArrayIndex] = false;
activeThreads--;
cout << "Thread '" << threadData.threadName << "is dead. His sacrifice will not be made in vain!\n";
pthread_mutex_unlock(&thread_mutex);
pthread_exit(NULL);
}
if (counter2 > 3)
{
// Return the last point
Point tempP = taken.back();
while (!tempP.isConnected(threadData.currentLocation))
{
taken.pop_back();
tempP = taken.back();
}
taken.push_back(threadData.currentLocation);
}
if (counter2 < 4)
{
taken.push_back(threadData.currentLocation);
}
if (threadData.currentLocation == endLocation)
{
if (!discoveredASolutionPath)
{
cout << "Thread '" << threadData.threadName << "' found a solution! Well done!\n";
// Block Out
pthread_mutex_lock(&thread_mutex);
addSolution(threadData.currentLocation, taken);
// Unlock
pthread_mutex_unlock(&thread_mutex);
areThreadsActive[threadData.threadIDArrayIndex] = false;
activeThreads--;
pthread_exit(NULL);
}
}
} while (!discoveredASolutionPath);
return EXIT_SUCCESS;
}
bool hitBoundary(Point tempCurrLoc)
{
if ((tempCurrLoc.x < 0) || (tempCurrLoc.x >= mazeObj->getLength()))
{
return true;
}
else if ((tempCurrLoc.y < 0) || (tempCurrLoc.y >= mazeObj->getBreadth()))
{
return true;
}
return false;
}
void addDanger(Point tempCurrLoc, VectorOfPointStructType tempTaken)
{
globalPathFinderResource.noOfDangerAreaDiscovered++;
globalPathFinderResource.discoveredDangerAreas.push_back(tempCurrLoc);
submittedPaths++;
taken.push_back(tempCurrLoc);
submitMazeSolnObj->submitPathToDangerArea(pthread_self(), taken);
mazeSolution->updateMaze(tempCurrLoc, DANGER_INT);
}
void addSolution(Point tempCurrLoc, VectorOfPointStructType tempTaken)
{
globalPathFinderResource.solutionPath = taken;
numSoln++;
submittedPaths++;
allPaths.push_back(taken);
submitMazeSolnObj->submitSolutionPath(pthread_self(), taken);
mazeSolution->AddNewPath(taken);
if (numSoln == maxNoOfSolutions)
{
discoveredASolutionPath = true;
}
}
void addBarrier(Point tempCurrLoc, VectorOfPointStructType tempTaken)
{
if (find(barriers.begin(), barriers.end(), tempCurrLoc) == barriers.end())
{
barriers.push_back(tempCurrLoc);
globalPathFinderResource.noOfBarriersDiscovered++;
}
submittedPaths++;
tempTaken.push_back(tempCurrLoc);
submitMazeSolnObj->submitPathToBarrier(pthread_self(), taken);
mazeSolution->updateMaze(tempCurrLoc, BARRIER_INT);
}
void * display(void * empty)
{
// Block Out
pthread_mutex_lock(&thread_mutex);
// Suspend execution for 4 seconds
usleep(4000000);
time(&endTime);
cout << "=======================================================\n";
cout << "Elasped Time: " << difftime(endTime, startTime) << "\n";
cout << "Latest Update: \n";
cout << "=======================================================\n";
cout << "\n";
cout << "Dead End Paths Found : " << globalPathFinderResource.noOfDeadEndPathsFound << "\n";
cout << "Barriers Discovered : " << globalPathFinderResource.noOfBarriersDiscovered << "\n";
cout << "Danger Area Discovered: " << globalPathFinderResource.noOfDangerAreaDiscovered << "\n";
cout << "\n";
areThreadsActive[2] = false;
// Unlock
pthread_mutex_unlock(&thread_mutex);
return EXIT_SUCCESS;
}
void statistics()
{
// Create an output buffer to store
streambuf * buffer;
ostream output(buffer);
// Capture all display
output << "Information:\n";
output << "Threads Active : " << globalPathFinderResource.usedThreadNameIndex << "\n";
output << "Paths Submitted : " << submittedPaths << "\n";
output << "Solutions Submitted: " << numSoln << "\n";
output << "\n";
output << "Discoveries:\n";
output << "Dead Ends Found : " << globalPathFinderResource.noOfDeadEndPathsFound << "\n";
output << "Barriers Found : " << globalPathFinderResource.noOfBarriersDiscovered << "\n";
output << "Danger Areas Found: " << globalPathFinderResource.noOfDangerAreaDiscovered << "\n";
output << "\n";
// Get the shortest path
VectorOfPointStructType final = getShortestPath();
output << "Shortest Path Found: ";
final.pop_back();
mazeObj->ShowPathGraphically(final, output);
}
VectorOfPointStructType getShortestPath()
{
int min = 0;
for(int i=1; i < allPaths.size(); i++)
{
if(allPaths[i].size() < allPaths[min].size())
min = i;
}
return allPaths[min];
}
程序,当我编译程序时,它没有显示任何错误消息。但是,当我运行该程序时,我在我的ubuntu机器上收到#ifndef MAZESOLVER_H
#define MAZESOLVER_H
#include <pthread.h>
#include "Path.h"
#include "Maze.h"
#include "SubmitMazeSoln.h"
#include "Assignm3_Utils.h"
#include "Assignm3.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctime>
#include <algorithm>
#include <unistd.h>
#include <signal.h>
#include <streambuf>
using namespace std;
using namespace Assignm3;
const string fileName = "mazedata.txt";
const string studentName = "Foo Ce Zhong";
const string studentID = "5363391";
Maze * mazeSolution;
VectorOfPointStructType barriers;
VectorOfVectorOfPointStructType allPaths;
time_t startTime, endTime;
bool areThreadsActive[MAX_NO_OF_THREADS];
VectorOfPointStructType taken;
VectorOfPointStructType checked;
int activeThreads;
int submittedPaths;
int numSoln;
int maxNoOfSolutions;
int start(); // start the process
int create(); // create threads
void explore(); // display paths
int end(); // end the process
void *findPath(void *);
void *display(void *);
bool hitBoundary(Point);
void addBarrier(Point, VectorOfPointStructType);
void addDanger(Point, VectorOfPointStructType);
void addSolution(Point, VectorOfPointStructType);
void statistics();
VectorOfPointStructType getShortestPath();
#endif
错误消息。
以下是我的c ++代码和头文件。
mazesolver.cpp
vmw_ubuntu@vmwubuntu:~/Desktop/Master$ ./mazesolver.exe
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 # # # # # # # # # # # # # # # # # # # #
1 # S # # #
2 # # # # # # # # # # # #
3 # # # # E #
4 # # # # X # X # # #
5 # X # # # # # # # # #
6 # # # # # # # #
7 # # # # # # # # # # # # # # #
8 # # #
9 # # # # # # # # # # # # # # # # # # # #
_length : 20
_breadth : 10
_startLocation : [ 1, 1 ]
_endLocation : [ 17, 3 ]
No. of paths discovered : 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0
1 S
2
3 E
4
5
6
7
8
9
_length : 20
_breadth : 10
_startLocation : [ 1, 1 ]
_endLocation : [ 17, 3 ]
No. of paths discovered : 0
Thread 'POOH' has been created!
Thread 'TIGGER' has been created!
Segmentation fault (core dumped)
mazesolver.h
{{1}}
我的可执行文件的输出
{{1}}
对不起垃圾邮件,但我想你们最好全面了解。谢谢你们!
答案 0 :(得分:0)
调试多线程程序需要关注完整的调试和对代码的理解。第一步是找到导致内存异常的函数。您可以使用gdb获取堆栈跟踪。
Run "gdb <exe name> <core file>"
On the gdb prompt type "where" to get the stack trace.
其他选项是使用调试器
运行可执行文件我还注意到你的代码使用小写的函数名,比如“create”, “启动”等。不建议使用,因为许多OS系统调用类似 名称,有时与用户定义的函数冲突,难以调试 如果程序是使用来自多个供应商的库构建的。