我正在使用线程和互斥量。但由于某种原因,我无法弄清楚为什么,我得到一些分段错误。无法使用gdb,因为我无法获得该错误= /
此外,我试图在线之间进行一些打印,但看不到任何相关信息......
有人可以告诉我为什么会这样吗?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
// Not order for easy random implementation
#define CITY_B 1
#define CITY_A 2
#define CITY_C 3
#define CITY_D 4
#define TRAIN_NUMBER 3
pthread_mutex_t lineAB;
pthread_mutex_t lineBC;
pthread_mutex_t lineBD;
typedef struct {
int num;
int from;
int to;
}Train;
int generateRandom(int min, int max, int seed) {
srand(time(NULL)+seed);
return ((rand()%max)+min);
}
char * getCurrentTime() {
char * timeString = (char *) malloc(sizeof(char) * 20);
time_t now = time(NULL);
strftime(timeString, 20, "%H:%M:%S", localtime(&now));
return timeString;
}
char * hora() {
return getCurrentTime();
}
pthread_mutex_t * nextLine(int from, int to) {
switch(from) {
case CITY_A: {
return &lineAB;
}
case CITY_B: {
switch(to) {
case CITY_A: {
return &lineAB;
}
case CITY_C: {
return &lineBC;
}
case CITY_D: {
return &lineBD;
}
}
break;
}
case CITY_C: {
return &lineBC;
}
case CITY_D: {
return &lineBD;
}
}
}
char * getCityName(int num) {
switch(num) {
case CITY_A: {
return "City A";
}
case CITY_B: {
return "City B";
}
case CITY_C: {
return "City C";
}
case CITY_D: {
return "City D";
}
}
}
char * getLineName(int from, int to) {
switch(from) {
case CITY_A: {
return "cityA-cityB";
break;
}
case CITY_B: {
switch(to) {
case CITY_A: {
return "cityA-cityB";
break;
}
case CITY_C: {
return "cityB-cityC";
break;
}
case CITY_D: {
return "cityB-cityD";
break;
}
}
break;
}
case CITY_C: {
return "cityB-cityC";
break;
}
case CITY_D: {
return "cityB-cityD";
break;
}
}
}
void * threadFunc(void *arg){
Train * train = (Train*)arg;
/*int trainNum = info[0];
int from = info[1];
int to = info[2];*/
char * partida = hora();
char * chegada;
printf("Train %d, From: %s, To: %s\n", train->num, getCityName(train->from), getCityName(train->to));
//printf("A\n");
pthread_mutex_t * myMutex = nextLine(train->from, CITY_B);
pthread_mutex_lock(myMutex);
//printf("B\n");
printf("Train: %d\tLine: %s\tFrom: %s\tTo: %s\n", train->num,
getLineName(train->from, CITY_B), getCityName(train->from), getCityName(train->to));
// Each line takes x sec to finish
//printf("C\n");
sleep(3);
//printf("D\n");
pthread_mutex_unlock(myMutex);
//printf("E\n");
myMutex = nextLine(CITY_B, train->to);
//printf("F\n");
printf("Train: %d\tLine: %s\tFrom: %s\tTo: %s\n", train->num,
getLineName(CITY_B, train->to), getCityName(train->from), getCityName(train->to));
// Each line takes x sec to finish
//printf("G\n");
sleep(3);
//printf("H\n");
pthread_mutex_unlock(myMutex);
//printf("I\n");
chegada = hora();
//printf("J\n");
printf("\nTrain: %d\nDeparture: %s\tArrival: %s\n\n", train->num, partida, chegada);
//printf("K\n");
pthread_exit((void*)NULL);
}
int main(char *arg, char **args){
pthread_t threads[TRAIN_NUMBER];
Train trains[TRAIN_NUMBER];
lineAB = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
lineBC = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
lineBD = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
srand(time(NULL));
int i;
for (i = 0; i < TRAIN_NUMBER; ++i) {
trains[i].num = i+1;
trains[i].from = generateRandom(CITY_A, CITY_D, i);
if(trains[i].from == CITY_A) {
trains[i].to = generateRandom(CITY_C, CITY_D, i);
} else {
trains[i].to = CITY_A;
}
pthread_create(&threads[i],NULL,threadFunc,(void*)&trains[i]);
}
for(i = 0; i < TRAIN_NUMBER; i++) {
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&lineAB);
pthread_mutex_destroy(&lineBC);
pthread_mutex_destroy(&lineBD);
return 0;
}
以下是代码的一些结果!
示例1(在打印任何内容之前):
make: *** [run] Segmentation fault
示例2:
Train 1, From: City D, To: City A
Train: 1 Line: cityB-cityD From: City D To: City A
Train 3, From: City D, To: City A
make: *** [run] Segmentation fault
示例3:
Train 1, From: City A, To: City C
Train: 1 Line: cityA-cityB From: City A To: City C
Train 2, From: City A, To: City C
Train 3, From: City C, To: City A
Train: 3 Line: cityB-cityC From: City C To: City A
Train: 1 Line: cityB-cityC From: City A To: City C
Train: 3 Line: cityA-cityB From: City C To: City A
Train: 2 Line: cityA-cityB From: City A To: City C
Train: 2 Line: cityB-cityC From: City A To: City C
Train: 1 Departure: 18:51:55 Arrival: 18:52:01
Train: 3 Departure: 18:51:55 Arrival: 18:52:01
Train: 2 Departure: 18:51:55 Arrival: 18:52:04
答案 0 :(得分:1)
我用
运行程序ulimit -c unlimited
这会导致生成核心文件。现在可以运行gdb。
调试此核心文件显示错误在此行:
printf("Train %d, From: %s, To: %s\n", train->num, getCityName(train->from), getCityName(train->to));
印刷列车给出:
(gdb)print * train
$ 3 = {num = 3,从= 5到= 2}
所以train-&gt; from无效(有效期为1-4)!
使用generateRandom()生成train-&gt; to和train-&gt; from,因此bug必须在这里。
int generateRandom(int min, int max, int seed) {
srand(time(NULL)+seed);
return ((rand()%max)+min);
}
rand()%max可以生成从0到最大-1的数字。将min添加到此可以给出max + min-1。由于输入为2(CITY_A)和4(CITY_D),您可以获得2到5之间的数字。您可能需要这样:
int generateRandom(int min, int max, int seed) {
srand(time(NULL)+seed);
return ((rand()%(max-min))+min);
}
答案 1 :(得分:0)
发布的代码包含大量问题,其中大部分都在评论中指出。
但是,主要问题在于此行的generateRandom()
函数:
return ((rand()%max)+min);
生成的值大于3(典型值为5)
然后,在代码的后面,对mutex数组的访问是在数组末尾之外访问的。
然后对pthread_mutex_lock()
的调用被输入无效指针,导致seg fault事件。
使用gdb
调试程序的两次传递以及对printf()
的一些“有用”调用可以快速找到问题的根源。
强烈建议您对调试器非常熟悉。
这是我用于调试的代码版本:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> // rand(), srand()
#include <unistd.h>
// Not order for easy random implementation
#define CITY_B 1
#define CITY_A 2
#define CITY_C 3
#define CITY_D 4
#define TRAIN_NUMBER 3
pthread_mutex_t lineAB = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lineBC = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lineBD = PTHREAD_MUTEX_INITIALIZER;
struct TrainStruct
{
size_t num;
size_t from;
size_t to;
};
typedef struct TrainStruct Train;
size_t generateRandom(int min, int max, size_t seed)
{
(void)seed;
//srand(time(NULL)+seed);
return (size_t)((rand()%max)+min);
}
char * getCurrentTime()
{
char * timeString = malloc(20);
time_t now = time(NULL);
strftime(timeString, 20, "%H:%M:%S", localtime(&now));
return timeString;
} // end function: getCurrentTime
char * hora() {
return getCurrentTime();
}
pthread_mutex_t * nextLine(size_t from, size_t to)
{
switch(from)
{
case CITY_A:
return &lineAB;
break;
case CITY_B:
switch(to)
{
case CITY_A:
return &lineAB;
break;
case CITY_C:
return &lineBC;
break;
case CITY_D:
return &lineBD;
break;
default:
printf( "invalid train.to: %lu\n", to);
return NULL;
break;
} // end switch
break;
case CITY_C:
return &lineBC;
break;
case CITY_D:
return &lineBD;
break;
default:
printf( "invalid train.from: %lu\n", from);
return NULL;
break;
} // end switch
}
char * getCityName(size_t num)
{
switch(num)
{
case CITY_A:
return "City A";
break;
case CITY_B:
return "City B";
break;
case CITY_C:
return "City C";
break;
case CITY_D:
return "City D";
break;
default:
printf( "invalid city num: %lu\n", num);
return NULL;
break;
} // end switch
}
char * getLineName( size_t from, size_t to)
{
switch(from)
{
case CITY_A:
return "cityA-cityB";
break;
case CITY_B:
switch(to)
{
case CITY_A: {
return "cityA-cityB";
break;
}
case CITY_C:
return "cityB-cityC";
break;
case CITY_D:
return "cityB-cityD";
break;
default:
printf( "invalid train.to: %lu\n", to);
return NULL;
break;
} // end switch
break;
case CITY_C:
return "cityB-cityC";
break;
case CITY_D:
return "cityB-cityD";
break;
default:
printf( "invalid train.from: %lu\n", from);
return NULL;
break;
} // end switch
}
void * threadFunc(void *arg)
{
Train * train = (Train*)arg;
/*int trainNum = info[0];
int from = info[1];
int to = info[2];*/
char * partida = hora();
char * chegada;
// for testing
printf( "func:%s\n num: %lu\n from: %lu\n to: %lu\n\n",
__func__,
train->num,
train->from,
train->to);
printf("Train %lu, From: %s, To: %s\n\n",
train->num,
getCityName(train->from),
getCityName(train->to));
//printf("A\n");
pthread_mutex_t * myMutex = nextLine(train->from, CITY_B);
pthread_mutex_lock(myMutex);
//printf("B\n");
printf("Train: %lu\tLine: %s\tFrom: %s\tTo: %s\n",
train->num,
getLineName(train->from, CITY_B),
getCityName(train->from),
getCityName(train->to));
// Each line takes x sec to finish
//printf("C\n");
sleep(3);
//printf("D\n");
pthread_mutex_unlock(myMutex);
//printf("E\n");
myMutex = nextLine(CITY_B, train->to);
//printf("F\n");
printf("Train: %lu\tLine: %s\tFrom: %s\tTo: %s\n",
train->num,
getLineName(CITY_B, train->to),
getCityName(train->from),
getCityName(train->to));
// Each line takes x sec to finish
//printf("G\n");
sleep(3);
//printf("H\n");
pthread_mutex_unlock(myMutex);
//printf("I\n");
chegada = hora();
//printf("J\n");
printf("\nTrain: %lu\nDeparture: %s\tArrival: %s\n\n",
train->num,
partida,
chegada);
//printf("K\n");
pthread_exit((void*)NULL);
}
int main( void )
{
pthread_t threads[TRAIN_NUMBER];
Train trains[TRAIN_NUMBER];
srand((unsigned)time(NULL));
for (size_t i = 0; i < TRAIN_NUMBER; ++i)
{
trains[i].num = i+1;
trains[i].from = generateRandom(CITY_A, CITY_D, i);
if(trains[i].from == CITY_A)
{
trains[i].to = generateRandom(CITY_C, CITY_D, i);
}
else
{
trains[i].to = CITY_A;
}
pthread_create(&threads[i],NULL,threadFunc,(void*)&trains[i]);
}
for(size_t i = 0; i < TRAIN_NUMBER; i++)
{
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&lineAB);
pthread_mutex_destroy(&lineBC);
pthread_mutex_destroy(&lineBD);
} // end function: main