-1

I'm experimenting with concurrent programming in C using the Codeblocks IDE with gcc. When I run my program, I receive no output. Interestingly, though, when I put a breakpoint at a certain point in the program, the program will execute all instructions (including outputting values to the console) up to that point. However, afterwards, if I try to execute the instruction srand(time(NULL)), all of the variables that I'm watching immediately show "Error reading variable, cannot access memory at address X" and the debugging process halts.

Here is my main() function

/*main function*/
int main()
{
int k = 3;
int m = 100;
int n = 10;
int t = 10;

/*First, let's create the threads*/
pthread_t thread[numOfThreads];

/*Second, create the data struct*/
struct programData *data = malloc(sizeof(struct programData));

/*Initialize data struct*/
data->kPumps=k;
data->mVisitors=m;
data->nCars=n;
data->tTime=t; /*They'll drive visitor around for 10 units of time.*/

/*Now let's create the different threads*/
pthread_create(&thread[0], NULL, visitorThread, (void*)data);
pthread_create(&thread[1], NULL, carThread, (void*)data);
pthread_create(&thread[2], NULL, pumpThread, (void*)data);
pthread_create(&thread[3], NULL, gasTruck, (void*)data);

return 0;
}

And my visitor thread

void *visitorThread(void *arg){
int arrayIndex;
int i;
/*Let's create mVisitors*/
struct programData *data;
data = (struct programData*)arg;
int numOfVisitors;
numOfVisitors = data->mVisitors;
/*create an array of visitors*/
struct visitor v[numOfVisitors];

/*Initialize values*/
for(i = 0; i < numOfVisitors; i++){
    v[i].id = i+1;
    v[i].isInCar = false;
    v[i].isInQueue = false;
}

printf("There are %d visitors at the San Diego Zoo \n", numOfVisitors);
printf("At first the visitors wait at the snake exhibit \n");
//sleep(5);
printf("Now some of them are getting bored, and want to get into a car to be shown the rest of the zoo \n");

/*After a random amount of time, some people line up to take cars*/
/*create queue*/
struct visitor* queue[numOfVisitors];
/*Initialize the array*/
for(i = 0; i < numOfVisitors; i++){
    queue[i] = NULL;
}

arrayIndex = 0;

/*While there are people in the snake exhibit*/
while(numOfVisitors >=1){
    /*After a random period of time, no more than 5 seconds...*/
//srand
    srand(time(NULL));
    int timeBeforePersonLeaves = rand()%5+1;
    //fflush(stdout);
    //sleep(timeBeforePersonLeaves);
    /*...a random person will get bored and enter the array line to be picked up by a car*/
    srand(time(NULL));
    int personIndex = rand() % numOfVisitors;
    queue[arrayIndex] = &v[personIndex];
    v[personIndex].isInQueue = true;
    printf("Visitor %d is now in queue spot %d \n", personIndex, arrayIndex);
    arrayIndex++;
}
return;
}

The problem seems to exist within the while loop. If I put a breakpoint at the bracket at the end of the while loop, it will output every value. However, if put the breakpoint anywhere within the while loop, as soon as it reaches the srand call, it leads to the same issue. Any help regarding this would be appreciated, and thanks in advance.

Johnny
  • 105
  • 1
  • 13
  • 2
    `while(numOfVisitors >=1)`. You have an infinete loop. Results in `arrayIndex` growing continuously and overflowing `queue`. Also, read the [man page for srand](http://linux.die.net/man/3/srand). You only need call that once not continuously. – kaylum Dec 03 '15 at 02:49
  • calling srand once seems to have fixed the issue. Thanks! – Johnny Dec 03 '15 at 02:54
  • Unfortunately I doubt that would have fixed your underlying problem. It may have moved the problem so that it doesn't trigger in your current test runs (common occurrence with multi-threaded applications). But unless you fix the underlying issues (such as the infinete loop) problems are going to bite you again at any time. – kaylum Dec 03 '15 at 02:57
  • I should have noted that I added code to decrement numOfVisitors, which halts the while loop. – Johnny Dec 03 '15 at 04:12
  • 1
    Ok, that is more likely to have fixed your seg fault than the `srand` change. – kaylum Dec 03 '15 at 04:13
  • regarding this line: `pthread_t thread[numOfThreads];` 1) the data being defined is placeholders for the threadIDs, not the actual threads. Suggest fixing the array name. 2) thevalue: `numOfThreads` is not defined in the posted code – user3629249 Dec 03 '15 at 09:12
  • regarding this line: `struct programData *data = malloc(sizeof(struct programData));`, 1) the `struct programData` is not defined in the posted code. 2) always check (!=NULL) the returned value to assure the operation was successful – user3629249 Dec 03 '15 at 09:14
  • regarding this kind of line: `pthread_create(&thread[0], NULL, visitorThread, (void*)data);`, always check the returned value to assure the operation was successful. – user3629249 Dec 03 '15 at 09:16
  • in the `main()` function, before this line: `return 0;`, need to call `pthread_join()` for each entry in the `thread[]` array. Otherwise the `main()` function exits, resulting in all the threads also exiting, even though they are not finished. – user3629249 Dec 03 '15 at 09:18
  • regarding this line: `struct visitor* queue[numOfVisitors];` the `struct visitor` is not defined in the posted code – user3629249 Dec 03 '15 at 09:20
  • regarding this line: `srand(time(NULL));`, The `srand()` function should be called ONLY once in the whole program execution, suggest calling near the top of the `main()` function. – user3629249 Dec 03 '15 at 09:22
  • this expression: `rand()%5+1;` can get messed up due to the precedence rules. Suggest: `1+ rand()%5;` – user3629249 Dec 03 '15 at 09:24
  • regarding this statement: `while(numOfVisitors >=1){`, within the loop, the variable: `numOfVisitors` is never decremented, so this loop will run forever. – user3629249 Dec 03 '15 at 09:28
  • there is nothing in the posted code to stop the same visitor `v[x]` from being selected over and over and over and over... – user3629249 Dec 03 '15 at 09:29
  • regarding this statement in the thread function: `return;`, That is not the correct way to exit a thread. Suggest using: `pthread_exit( &status );` --or-- `pthread_exit( NULL );` – user3629249 Dec 03 '15 at 09:32
  • decrementing the variable `numOfVisitor` is not a complete fix to the while loop. This is because each visitor must be (eventually) moved to the `queue` and marked as `inQueue = true;` and with the way the code is currently written, if the highest numbered visitor is not selected on each iteration through the `while` loop, and the numOfVisitors is decremented on each loop, then that visitor will never be moved to the `queue` – user3629249 Dec 03 '15 at 09:39

1 Answers1

0

while(numOfVisitors >=1). You have an infinete loop. Results in arrayIndex growing continuously and overflowing queue. Also, read the man page for srand. You only need call that once not continuously. – kaylum

Armali
  • 18,255
  • 14
  • 57
  • 171