这是有问题的功能:
#include <cstdlib>
#include <string>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "Train.h"
#include "Platform.h"
const int NUM_TRAINS = 4;
const int NUM_NORTHERNLY_TRAINS = NUM_TRAINS / 2;
const int NUM_SOUTHERNLY_TRAINS = NUM_TRAINS - NUM_NORTHERNLY_TRAINS;
const int NUM_LOOPS = 16;
const char* TRAIN_NAME_ARRAY[NUM_TRAINS]
= { "Thomas the Tank-Engine",
"Percy the Small Engine",
"California Zephyr",
"Tokaido Shinkansen"
};
const int TRAIN_TRANSIT_TIME_MSECS[NUM_TRAINS]
= { 10000, // Thomas
10000, // Percy
5000, // CA Zephyr
1000 // Bullet train
};
Platform northBoundPlatform("North-bound Platform");
Platform southBoundPlatform("South-bound Platform");
void* initiallyNorthernly (void* vPtr)
{
Train* id = ((Train*)vPtr);
for (int i = 0; i < NUM_LOOPS; i++)
{
northBoundPlatform.arrive(id);
northBoundPlatform.leave();
pause();
southBoundPlatform.arrive(id);
southBoundPlatform.leave();
pause();
}
return((void*)id);
}
void* initiallySouthernly (void* vPtr)
{
Train* id = (Train*)vPtr;
for (int i = 0; i < NUM_LOOPS; i++)
{
southBoundPlatform.arrive(id);
southBoundPlatform.leave();
pause();
northBoundPlatform.arrive(id);
northBoundPlatform.leave();
pause();
}
return((void*)id);
}
int main ()
{
pthread_t tidArray[NUM_TRAINS];
Train* trainArray[NUM_TRAINS];
pthread_t tidArray2[NUM_NORTHERNLY_TRAINS];
Train* trainArray2[NUM_NORTHERNLY_TRAINS];
pthread_t tidArray3[NUM_SOUTHERNLY_TRAINS];
Train* trainArray3[NUM_SOUTHERNLY_TRAINS];
for (int i = 0; i < NUM_TRAINS; i++)
{ trainArray[i] = new Train(TRAIN_NAME_ARRAY[i],TRAIN_TRANSIT_TIME_MSECS[i]);
}
int trainInd = 0;
for (int i = 0; i < NUM_NORTHERNLY_TRAINS; i++)
{
pthread_create(&tidArray2[i], NULL, initiallyNorthernly,&trainArray2[i]);
}
for (int i = 0; i < NUM_SOUTHERNLY_TRAINS; i++)
{
pthread_create(&tidArray3[i], NULL, initiallySouthernly,&trainArray3[i]);
}
for (int i = 0; i < NUM_TRAINS; i++)
{
trainArray[i] = NULL;
// Wait for all Train threads. Also, get the pointers to the Train objects
// and delete() them because they were created by 'new'
pthread_join(tidArray[i], (void**)&trainInd);
pthread_join(tidArray2[i],(void**)&trainInd);
pthread_join(tidArray3[i],(void**)&trainInd);
}
return(EXIT_SUCCESS);
}
以下是相应的头文件:
Train.h
class Train
{
std::string name_;
int pauseTimeUsecs_;
public :
Train (const std::string& newName,
int newPauseTimeUsecs
)
{
name_ = newName;
pauseTimeUsecs_ = newPauseTimeUsecs;
std::cout << getName() << " leaving the trainyard.\n";
}
~Train ()
{
std::cout << getName() << " going back to the trainyard\n";
}
const std::string&
getName ()
const
{ return(name_); }
void pause ()
const
{
usleep(pauseTimeUsecs_);
}
};
Platform.h
class Platform
{
std::string name_;
Train* trainPtr_;
pthread_mutex_t mutexLock_;
pthread_cond_t notEmptyCond_;
pthread_cond_t notFullCond_;
public :
Platform (const std::string& newName
)
{
name_ = newName;
trainPtr_ = NULL;
pthread_mutex_init(&mutexLock_,NULL);
pthread_cond_init(¬EmptyCond_,NULL);
pthread_cond_init(¬FullCond_,NULL);
}
// PURPOSE: To release resources. No parameters. No return value.
~Platform ()
{
pthread_mutex_destroy(&mutexLock_);
pthread_cond_destroy(¬EmptyCond_);
pthread_cond_destroy(¬FullCond_);
}
const std::string&
getName ()
const
{
return(name_);
}
Train* getTrainPtr
()
const
{
return(trainPtr_);
}
void arrive (Train* newTrainPtr
)
{
pthread_mutex_lock(&mutexLock_);
while (getTrainPtr() != NULL)
{
std::cout << getTrainPtr()->getName()
<< " is at " << getName()
<< ", " << newTrainPtr->getName()
<< " must wait.\n";
usleep(10) + rand() % 10;
pthread_cond_wait(¬FullCond_,&mutexLock_);
}
std::cout << newTrainPtr->getName() << " arriving at " << getName() << "\n";
trainPtr_ = newTrainPtr;
usleep(10 + rand() % 10);
pthread_mutex_unlock(&mutexLock_);
pthread_cond_signal(¬EmptyCond_);
}
Train* leave ()
{
pthread_mutex_lock(&mutexLock_);
while (getTrainPtr() == NULL)
{
std::cout << "No train at " << getName() << "!\n";
usleep(10 + rand() % 10);
pthread_cond_wait(¬EmptyCond_,&mutexLock_);
}
Train* toReturn = getTrainPtr();
std::cout << toReturn->getName() << " leaving " << getName() << "\n";
usleep(10 + rand() % 10);
trainPtr_ = NULL;
pthread_cond_signal(¬FullCond_);
pthread_mutex_unlock(&mutexLock_);
return(toReturn);
}
};
使用gdb运行后,当我调用northBoundPlatform(Platform对象)时出现分段错误。该函数的目标是使vPtr指向的训练对象到达Northern平台的到达(),在northernPlatform留下(),在train对象上的pause(),在southBoundPlatform的到达(),离开()到southBoundPlatform,再次对该对象执行pause(),最后返回指向所使用的火车的指针。
我不确定我是否正确地将vPtr投射到Train *中导致分段错误。如有必要,我可以提供其余的主要代码。任何帮助表示赞赏。
答案 0 :(得分:1)
你的main()函数为每个NUM_NORTHERNLY_TRAINS都有两个for循环,使用initialNorthernly和initialSouthernly,但是第二个循环应该用NUM_SOUTHERNLY_TRAINS循环。