我是C ++新线程的新手,我确信它会在我的问题中显示出来。
我正在为一所学校的项目工作,我需要建立一个4路交通路口的模型,其中汽车是线程。我有一个时钟计数器,每个时钟滴答我生成一个随机数量的汽车,为每一个创建一个简单的汽车对象,将新车放入4个队列(街道)中的一个,然后做一个pthread来处理汽车。每辆车必须等到它到达街道的前面,然后等待一个信号,表明一辆车可以去。因此,如果有多辆汽车在十字路口等候,那么首先没有任何订单。
但是,我遇到了问题。根据我的打印输出,一个线程将运行,退出,但然后它将再次返回等待信号量。当它获得信号量并尝试用汽车做事时,这会发生段错误。任何正确方向的指针都会很棒!示例输出为:
Running with 10 cars
| | |
2: Generating 3 cars. Already scheduled: 0, finished: 0
2: Generating car 2-0 at street 3
2: Generating car 2-1 at street 3
2: Generating car 2-2 at street 0
waiting for clk in main
2-2 waiting for turn
2: Car 2-2 driving from street 0
waiting for streets in departure
2-2 | | | 2-0, 2-1
| | | 2-0, 2-1
releasing streets in departure
2-2 releasing clock
2-2 exiting
got clk in main
| | | 2-0, 2-1
4: Generating 3 cars. Already scheduled: 3, finished: 1
2-22-2 waiting for turn
4: Generating car 4-0 at street 1
waiting for turn
4: Generating car 4-1 at street 1
4: Generating car 4-2 at street 2
4-2 waiting for turn
waiting for clk in main
4: Car 2-2 driving from street 0
waiting for streets in departure
| 4-0, 4-1 | 4-2 | 2-0, 2-1
Segmentation fault (core dumped)
我的主要方法:
int numCars = 0;
deque<deque<Car> > streets; //each queue for each street
bool empty = true; // intersection is empty (Boolean)
int clk = 0; // clock counter
int carsFinished = 0;
int carsScheduled = 0;
sem_t turn;
sem_t streetSem;
sem_t sigSem;
sem_t clkSem;
int main () {
deque<Car> street0, street1, street2, street3;
streets.push_back(street0);
streets.push_back(street1);
streets.push_back(street2);
streets.push_back(street3);
printf("Please enter the number of cars to run: ");
cin >> numCars;
cout << "\nRunning with " << numCars << " cars\n";
sem_init(&turn, 0, 0);
sem_init(&streetSem, 0, 1);
sem_init(&sigSem, 0, 0);
sem_init(&clkSem, 0, 0);
while (carsFinished < numCars) {
// Generate a random number of cars, from 0 to 5
double r = rndom();
int numCarsThisRound;
if (r == 1.0) {
numCarsThisRound = 5; // so it won't go to 6
} else {
numCarsThisRound = r * 6.0;
}
int i = 0;
if ((carsScheduled < numCars) && ((carsScheduled - carsFinished) < 110) && (i < numCarsThisRound)) {
sem_wait(&streetSem);
print_streets();
sem_post(&streetSem);
cout << clk << ": Generating " << numCarsThisRound << " cars. Already scheduled: " << carsScheduled << ", finished: " << carsFinished << "\n";
}
// there are still cars there aren't more than 110 cars waiting we don't go over the number of cars for this clock
while ((carsScheduled < numCars) && ((carsScheduled - carsFinished) < 110) && (i < numCarsThisRound)) {
// assign each car to a random street
double r = rndom();
int num;
if (r == 1.0) {
num = 3; // so it won't go to 4
} else {
num = r * 4.0;
}
// make new car
Car car;
car.setQueue(num);
std::ostringstream s;
s << clk << "-" << i;
std::string id(s.str());
car.setId(id);
cout << clk << ":\tGenerating car " << car.id << " at street " << num << "\n";
sem_wait(&streetSem);
// if this is the first car in a street, let it know
if (streets[num].empty())
car.isFront = true;
streets[num].push_back(car);
sem_post(&streetSem);
// make new thread for that car
pthread_t pt;
pthread_create(&pt, NULL, &arrival, (void *)&car);
carsScheduled++;
i++;
}
// if there's a car that should go this clk
if (!streetsAreEmpty()) {
// wait until that car runs before incrementing clk
sem_post(&turn);
cout << "waiting for clk in main\n";
sem_wait(&clkSem);
cout << "got clk in main\n";
}
clk++;
}
return (0);
}
线程使用的其他方法:
// car arrives at street
void* arrival(void *v) {
Car car = *(Car*)v;
// block until I'm at the front of the queue
while (true) {
if (car.isFront) {
break;
}
}
cout << car.id << " waiting for turn\n";
sem_wait(&turn); // wait for it to be someone's turn
cout << car.id << " waiting for signal\n";
cout << clk << ": Car " << car.id << " driving from street " << car.queue << "\n";
drive();
departure(car.queue);
cout << car.id << " releasing clock\n";
sem_post(&clkSem); // let the main method know I'm done
cout << car.id << " exiting\n";
pthread_exit(NULL);
}
// departure of car from intersection
void departure(int i) {
// one car departs
cout << "waiting for streets in departure\n";
sem_wait(&streetSem);
print_streets();
streets[i].pop_front();
if (!streets[i].empty()) {
streets[i].front().isFront = true;
}
print_streets();
cout << "releasing streets in departure\n";
sem_post(&streetSem);
carsFinished++;
}
// take up a clock tick to simulate driving
void drive() {
clk++;
}
Car类标题 - 非常简单:
#ifndef CAR_H
#define CAR_H
class Car {
#include <string>
public:
Car();
Car(int);
void setQueue(int);
void setId(std::string);
std::string id;
int queue;
bool isFront;
};
#endif
谢谢!
答案 0 :(得分:1)
这是未定义的行为。
Car car
是一个局部变量,一旦超出范围就会被销毁。
您假设在此之前制作了副本(Car car = *(Car*)v;
),但这不一定正确。
改变汽车的使用寿命,每个螺纹应该有(一个堆分配?)。