1

I am compiling this code with g++:

#include <pthread.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include <stdio.h>

using namespace std;

#define num_threads 3
#define car_limit 4

pthread_mutex_t mutex; // mutex lock
pthread_t cid;         // thread id
pthread_attr_t attr;   // thread attrubutes

void *OneCar(void *dir);
void ArriveBridge(int *direction);
void CrossBridge();
void ExitBridge(int *direction);


int main()
{

    int dir[3] = {0,1,1};
    pthread_mutex_init(&mutex, NULL);
    pthread_attr_init(&attr);

    //cout<< "Pthread Create" << endl;
    printf("Pthread Create\n");

    for(int i = 0; i < num_threads; i++)
    {
        pthread_create(&cid, &attr, OneCar, (void *)&dir[i]);
    }


return 0;
}


void ArriveBridge(int *direction)
{
    //cout<<"Arrive"<<*direction << endl;
    int dr;

    if(*direction == 0)
        dr=0;
    else
        dr=1;

    printf("Arrive%d", dr);
}

void CrossBridge(int *dir)
{   
    char d;

    if(*dir == 0)
        d = 'N';
    else
        d = 'S';

    //cout<<"Crossing Bridge going:"<<d<<endl;
    printf("Crossing Bridge going %c", d);
}

void ExitBridge(int *direction)
{
    //cout<<"Exit" <<*direction<<endl;
    int dr;

    if(*direction == 0)
        dr=0;
    else
        dr=1;

    printf("Exit%d\n", dr);
}

void *OneCar(void *dir)
{
    int *cardir;
    cardir = (int *) dir;

    //cout<<*cardir;

    ArriveBridge(cardir);
    CrossBridge(cardir);
    ExitBridge(cardir);

    return 0;
}

and I am expecting this result printed to the screen:

> Pthread Create
> Arrive0Crossing Bridge going NExit0
> Arrive1Crossing Bridge going SExit1
> Arrive1Crossing Bridge going NExit1

But i get this instead:

Pthread Create
Arrive0Crossing Bridge going NExit0

Why doesnt it print the rest out?

Bramble
  • 1,375
  • 10
  • 38
  • 55

3 Answers3

3

Have you tried joining your threads at the end of main? It could be that the program is terminating before the other threads are completely finished.

Jeremiah Willcock
  • 27,461
  • 5
  • 68
  • 75
3

You need to use "pthread_join" in main to wait for all threads to exit before your program terminates. You should also use an array to hold the id of each thread that you create:

pthread_t cid[num_threads];  // thread id`

You'll then want to call join on every thread you create:

for(int i = 0; i < num_threads; i++)
{
    pthread_create(&cid[i], &attr, OneCar, (void *)&dir[i]);
}


for(int i = 0; i < num_threads; ++i)
{
   pthread_join(cid[i], NULL);
};

Running the modified code now gives:

Pthread Create
Arrive0Crossing Bridge going NExit0
Arrive1Crossing Bridge going SExit1
Arrive1Crossing Bridge going SExit1
Stephan
  • 927
  • 6
  • 9
1

You missed the newlines ("\n"):

printf("Arrive%d\n", dr);
printf("Crossing Bridge going %c\n", d);

Because of that, the streams are probably not flushed. Additionally, if you don't wait for your threads (pthread_join) your program will exit before the threads could do their work.

DarkDust
  • 85,893
  • 19
  • 180
  • 214
  • `\n` won't cause a stream to be flushed. – rubenvb Feb 25 '11 at 21:22
  • @rubenvb: Yes, it does. See for example [C primer plus](http://books.google.com/books?id=iRa-3L4jLhEC&pg=PA84&lpg=PA84&dq=printf+buffer+flush+new+line&source=web&ots=dXfybt2e9I&sig=2jZHctY3fcmVz1zI4y9JuE8NeWE&hl=en&sa=X&oi=book_result&resnum=6&ct=result#v=onepage&q&f=false). See also [this question](http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-string) which cites the relevant C99 section in one of the answers. – DarkDust Feb 26 '11 at 00:48
  • @DarkDust: Will the same behavior be present in C++? I was confusing this with `std::cout`, which doesn't flush without a call to `flush()` (either through a direct call or `std::endl`. – rubenvb Feb 26 '11 at 13:09
  • @rubenvb: According to [this doc](http://www.cplusplus.com/reference/iostream/manipulators/endl/): yes, `std::endl` does also flush the buffered stream. Interestingly, in [this question](http://stackoverflow.com/questions/213907/c-stdendl-vs-n) they say that for `std::cout`, the `\n` does *not* flush the stream, so `endl` is like `\n` plus `flush`. – DarkDust Feb 26 '11 at 18:00
  • @DarkDust: that's what I'm saying. I wonder how this works for `printf` in c++? – rubenvb Feb 26 '11 at 22:51
  • @rubenvb: According to the C99 standard, the `\n` in a `printf` yields an implicit flush for *line buffered* streams (which `stdout` is by default). – DarkDust Feb 27 '11 at 13:03
  • @DarkDust: yes, but the question is explicitely about C++, not C99. There *is* a difference. – rubenvb Feb 27 '11 at 13:38
  • @rubenvb: But he's using `printf`, it doesn't matter whether he is calling it from C or C++. His output bug stems from that. He has some commented out lines which use `cout` and `endl`, but it's the same problem here: if he omits the `endls` and thus the implicit flush, he's getting the bug. – DarkDust Feb 27 '11 at 14:40