Solved

multithread

Posted on 2006-11-27
27
533 Views
Last Modified: 2008-01-09
I am trying to make a program with several threads in it. This is what I have so far:

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 1000

typedef struct {
        int id;
        int *counter;
} parm;

void *hello(void *arg)
{
        parm *p=(parm *)arg;

        int delay = rand() %10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}
   
int main(int argc, char* argv[]) {
        int n,i;
        int counter;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;
   
        if (argc != 2)
        {
                cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
                return 1;  
 }
       
        n=atoi(argv[1]);
       
        if ((n < 1) || (n > MAX_THREAD))
        {
                cout << "The no of thread should between 1  and " << MAX_THREAD << "." << endl;

        return 1;
        }
       
        threads= new pthread_t[n]();
        pthread_attr_init(&pthread_custom_attr);
         
        /* Start up thread */
        p = new parm[n]();
        counter = 0;
       
        for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;  

 pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);

        }
       
        /* Synchronize the completion of each thread. */
         
        for (i=0; i<n; i++)
        {
       pthread_join(threads[i],NULL);
        }
        delete threads;
        delete p;
        return 0;
}
 }
       
I tried compiling and I got these errors, I am confused, how can I fixed it? I posted my error below:

-bash-3.00$ g++ -lpthread -o p_hello p_hello.c
p_hello.c: In function `void* hello(void*)':
p_hello.c:28: error: a function-definition is not allowed here before '{' token
p_hello.c:38: error: a function-definition is not allowed here before '{' token




0
Comment
Question by:shahrine99
  • 10
  • 6
  • 5
  • +3
27 Comments
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 18025266
You have an extra brace } at the end. Simply delete it.
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 18025270
#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 1000

typedef struct {
        int id;
        int *counter;
} parm;

void *hello(void *arg)
{
        parm *p=(parm *)arg;

        int delay = rand() %10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}
   
int main(int argc, char* argv[]) {
        int n,i;
        int counter;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;
   
        if (argc != 2)
        {
                cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
                return 1;  
 }
       
        n=atoi(argv[1]);
       
        if ((n < 1) || (n > MAX_THREAD))
        {
                cout << "The no of thread should between 1  and " << MAX_THREAD << "." << endl;

        return 1;
        }
       
        threads= new pthread_t[n]();
        pthread_attr_init(&pthread_custom_attr);
         
        /* Start up thread */
        p = new parm[n]();
        counter = 0;
       
        for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;  

 pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);

        }
       
        /* Synchronize the completion of each thread. */
         
        for (i=0; i<n; i++)
        {
       pthread_join(threads[i],NULL);
        }
        delete threads;
        delete p;
        return 0;
}
/* }  You need to delete this brace. */
0
 

Author Comment

by:shahrine99
ID: 18025279
I did delete that brace then I get an error message that I need another brace there
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 18025681
Now compile this indented code.
Give a new-line after your code ends.

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 1000

typedef struct {
      int id;
      int *counter;
} parm;


void *hello(void *arg)
{
      parm *p=(parm *)arg;
      
      int delay = rand() %10;
      cout << "Node " << p->id << ", sleeping for " << delay << endl;
      sleep(delay);
      *p->counter += 1;
      cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
      return (NULL);
}


int main(int argc, char* argv[])
{
      int n,i;
      int counter;
      pthread_t *threads;
      pthread_attr_t pthread_custom_attr;
      parm *p;
      
      if (argc != 2)
      {
            cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
            return 1;  
      }
      
      n=atoi(argv[1]);
      
      if ((n < 1) || (n > MAX_THREAD))
      {
            cout << "The no of thread should between 1  and " << MAX_THREAD << "." << endl;
            
        return 1;
      }
      
      threads= new pthread_t[n]();
      pthread_attr_init(&pthread_custom_attr);
      
      /* Start up thread */
      p = new parm[n]();
      counter = 0;
      
      for (i=0; i<n; i++)
      {
            p[i].counter = &counter;
            p[i].id=i;  
            
            pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);
            
      }
      
      /* Synchronize the completion of each thread. */
      
      for (i=0; i<n; i++)
      {
            pthread_join(threads[i],NULL);
      }

      delete threads;
      delete p;
      return 0;
}
0
 
LVL 6

Expert Comment

by:_iskywalker_
ID: 18026872
i think you must declare:
void hello(void *arg) {
//the normal things here
}
int main(int argc, char* argv[])
{
int (*pt2Function)(void *arg) = &hello;
...
pthread_create(&threads[i], &pthread_custom_attr, pt2Function, (void *)&p[i]);
...
}

so changing declaration and declaring a variable pointer function and assingng hello to it. surely you must change the pthread_create statment then.
0
 
LVL 6

Expert Comment

by:_iskywalker_
ID: 18026875
if the pthread_create causes problems try:
pthread_create(&threads[i], &pthread_custom_attr, *pt2Function, (void *)&p[i]);
0
 
LVL 8

Expert Comment

by:deepu chandran
ID: 18027133
hi,

No need to assign the Function to a function pointer,you can directly use the function

thrd1=pthread_create(&threads[i],NULL,hello,(void *)&p[i]);

Deepu
0
 
LVL 6

Expert Comment

by:_iskywalker_
ID: 18027215
yes, sorry thought he used void *hello, chase he wanted a function pointer..
0
 
LVL 6

Expert Comment

by:_iskywalker_
ID: 18027240
you should use but at the end of hello:
pthread_exit(NULL);
instead of return (NULL);
it is much saver.
0
 

Author Comment

by:shahrine99
ID: 18029545
hey guyz, i fixed my program and now its working and compiled perfectly. i copied and pasted my revised program below so u can see. after the program is how my output looks like. please go all the way to the bottom so you can see what is my question......

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 1000

typedef struct {
        int id;
        int *counter;
} parm;

void *hello(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}

int main(int argc, char* argv[]) {
        int n,i;
        int counter;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;

        if (argc != 2)
        {
                cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
                return 1;
        }

        n=atoi(argv[1]);

        if ((n < 1) || (n > MAX_THREAD))
        {
                cout << "The no of thread should between 1 and " << MAX_THREAD << "." << endl;
                return 1;
        }

        threads= new pthread_t[n]();
        pthread_attr_init(&pthread_custom_attr);

        /* Start up thread */
        p = new parm[n]();
        counter = 0;

        for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;
                pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);
        }

        /* Synchronize the completion of each thread. */

        for (i=0; i<n; i++)
        {
                pthread_join(threads[i],NULL);
        }
        delete threads;
        delete p;
        return 0;
}


THIS IS THE OUTPUT

Node 0, sleeping for 3
Node 1, sleeping for 6
Node 2, sleeping for 7
Node 3, sleeping for 5
Node 4, sleeping for 3
Hello from node 0, adding 1 to counter: 1
Hello from node 4, adding 1 to counter: 2
Hello from node 3, adding 1 to counter: 3
Hello from node 1, adding 1 to counter: 4
Hello from node 2, adding 1 to counter: 5

Now my question  is..with this program I provided above, I want to do some different like have different thread do something else or say something else instead of just saying hello. how can i do dat?
0
 
LVL 6

Expert Comment

by:_iskywalker_
ID: 18030038
now you could use functions pointers, you make an array, put the different functions on it, or just pass a different string (string array).
0
 

Author Comment

by:shahrine99
ID: 18034330
i am not getting it...explain again please
0
 
LVL 8

Expert Comment

by:deepu chandran
ID: 18034424
hi,

What he is telling to do is change the function pointer insted of function direcly

What you have to do is Declare the function pointer in the Begining.Then Assing the Address to the Pointer and pass that referance to the Thread.I think there is no need for this.In the Pthread_create() function will consider the function as a pointer.

Deepu
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18038838
>>>> i am not getting it...explain again please

You can have a different thread function for each thread, e. g.

void* hello(void* arg) { ... };
void* hello1(void* arg) { ... };
void* hello2(void* arg) { ... };
void* hello3(void* arg) { ... };
void* hello4(void* arg) { ... };
void* hello5(void* arg) { ... };
...

Then you can create an array of function pointers:

 typedef void* (*ThreadFunc)(void*);
 ThreadFunc funcArray[MAX_THREAD] = { hello, hello1, hello2, hello3, ...., hello_n);  

Maybe you should set MAX_THREAD to 10 or so. BTW, 1000 threads is too much for one process (especially if you don't know what to do for 2 threads...).

when creating the threads you pass the appropriate function:

    pthread_create(&threads[i], &pthread_custom_attr, funcArray[i], (void *)&p[i]);


Another way is to make a thread function that runs infinitely and waits for jobs:

void* threadFunc(void *arg)
{
        parm *p=(parm *)arg;
        cout << "Node " << p->id << endl;
        while (!p->stopped)    // the stopped member can be set by the main thread to terminate  a thread
        {
            // the idea is to manage a job queue in parm struct
            // the main thread would ask the user for new jobs and what thread should do it
            // then the main thread appends the new job (== function pointer or job class object)
            // to the thread's queue and signals a new job
            if (p->haveANewJob())    // check if job queue is not empty
            {
                  p->doJob();  // the arguments are all stored in struct parm
                  p->removeJobFromQueue();
            }
            sleep(1000);   // sleep a little while to give other threads a chance
         }
         return NULL;
    }
}

Regards, Alex



     




0
 

Author Comment

by:shahrine99
ID: 18042908
im still working on it and thinking about it..give me a while and i will see
0
 
LVL 11

Expert Comment

by:cup
ID: 18060059
Minor point - you don't need to typedef the struct.

Instead of

typedef struct {
        int id;
        int *counter;
} parm;

void *hello(void *arg)
{
        parm *p=(parm *)arg;

use

struct parm {
        int id;
        int *counter;
};

void *hello(void *arg)
{
        parm *p=(parm *)arg;
0
 

Author Comment

by:shahrine99
ID: 18082281
alex im still little confused with your explanation...you said
>>>>> You can have a different thread function for each thread, e. g.

void* hello(void* arg) { ... };
void* hello1(void* arg) { ... };
void* hello2(void* arg) { ... };
void* hello3(void* arg) { ... };
void* hello4(void* arg) { ... };
void* hello5(void* arg) { ... };

so the codes above, i add that to the beginning of my program? I am not proficient in programming, im just a beginner thats why im clueless
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18083183
>>>> so the codes above, i add that to the beginning of my program?

No. You would need to add the implementation of different functions to be able to pass different pointers to the threads when calling pthread_create:

// that is your original hello function
void *hello(void *arg)
{
        parm *p=(parm *)arg;

        int delay = rand() %10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}

// here is a different function called hello 1
void *hello1(void *arg)
{
        parm *p=(parm *)arg;

        int delay = rand() %10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello1 from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}

When calling pthread_create you can pass either hello or hello1, e. g.

       for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;
                if (i%2 == 0)  // even numbers 0, 2, 4, ...
                    pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);
                else /* odd numbers, 1, 3, 5, ...
                    pthread_create(&threads[i], &pthread_custom_attr, hello1, (void *)&p[i]);

        }

If you would create 10 threads and if you had 10 different functions you could pass a different function to each thread by means of an array as I described above. Instead of an array you also could use a switch statement:

       for (i=0; i<10; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;
                switch(i)
                {
                case 0:
                    pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]); break;
                case 1:
                    pthread_create(&threads[i], &pthread_custom_attr, hello1, (void *)&p[i]); break;
                case 2:
                    pthread_create(&threads[i], &pthread_custom_attr, hello2, (void *)&p[i]); break;
                /* and so on */
                }
        }
   
But the main problem is not a technical one. You would need to find senseful tasks for your threads beside of printing "hello" or "hello1". You could think of making lengthy queries in a database or each thread reads a different file and counts number of words, ...

Regards, Alex
0
 

Author Comment

by:shahrine99
ID: 18090213
what does segmentatin fault means? i got that error when i compiled my program
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18091530
>>>> what does segmentatin fault means?

Normally, it means that you are writing beyond array bounds or write to a NULL pointer. Try to get the crash by using the debugger.

Regards, Alex
0
 

Author Comment

by:shahrine99
ID: 18111371
ok i have made adjustment to my program and this is what i have so far and it compiles and i copied and pasted my output so u can see...at the end of this msg will be my question

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 100

typedef struct {
        int id;
        int *counter;
} parm;

void *hello(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "Node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Hello from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
//      *p->counter += 1;
//      cout << "Bonjour from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return (NULL);
}

void *bonjour(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "BNode " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Bonjour from node " << p->id << ", adding 1 to counter: " << *p->counter << endl;
        return(NULL);
}

int main(int argc, char* argv[]) {
        int n,i;
        int counter;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;

        if (argc != 2)
        {
                cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
                return 1;
        }

        n=atoi(argv[1]);

        if ((n < 1) || (n > MAX_THREAD))
        {
                cout << "The no of thread should between 1 and " << MAX_THREAD << "." << endl;
                return 1;
        }

        threads= new pthread_t[n]();
        pthread_attr_init(&pthread_custom_attr);

        /* Start up thread */
        p = new parm[n]();
        counter = 0;

        for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;
                if (i%2 == 0) //even numbers 0,2,4
                pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)&p[i]);
                else //odd number
                pthread_create(&threads[i], &pthread_custom_attr, bonjour, (void *)&p[i]);
        }

        /* Synchronize the completion of each thread. */

        for (i=0; i<n; i++)
        {
                pthread_join(threads[i],NULL);
        }
        delete threads;
        delete p;
        return 0;
}

and my output is :

-bash-3.00$ g++ -o Thread2 -lpthread Thread2.c
-bash-3.00$ ./Thread2 5
Node 0, sleeping for 3
BNode 1, sleeping for 6
Node 2, sleeping for 7
BNode 3, sleeping for 5
Node 4, sleeping for 3
Hello from node 0, adding 1 to counter: 1
Hello from node 4, adding 1 to counter: 2
Bonjour from node 3, adding 1 to counter: 3
Bonjour from node 1, adding 1 to counter: 4
Hello from node 2, adding 1 to counter: 5

I want to know is there anything else i can add to my program to see something more different? Please let me know
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18112001
>>>> I want to know is there anything else i can add to my program to see something more different?

Yes, I told you above. Forget the hello and bonjour functions and go back to where you called only a single thread function. Let your thread function run infinitely in a while loop. Call sleep for some milliseconds in the loop or the threads would eat all CPU time. Then, randomly send messages between the threads and simulate a chat. (you may take the messages randomly from an array. Give each thread an unique nickname (via array as well) and output the chat like:

Joe (node 1) to Sam (node 7): How do you do?
Mary (node 2) to Henry (node 5): I am very busy today.
... and so on

You can improve the whole thing by using two arrays. One with questions and one with answers. Then, if thread 3 got an question from thread 5, it would need to answer (take some answer from the answer array) prior to asking a question to some other thread. Make it thread-safe by using a mutex. In the main thread you have a while loop too. You could wait for user input where you might stop/restart threads or add some messages from the main thread or quit by gracefully stopping all threads (by sending an appropriate message to them).

Regards, Alex
0
 

Author Comment

by:shahrine99
ID: 18112185
hey alex, this is what i did so far

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
#define MAX_THREAD 100

typedef struct {
        int id;
        int *counter;
} parm;

void *question(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "Joe from node " << p->id << ", sleeping for " << delay << " milliseconds." << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Joe from node " << p->id << ", to Sam from node " << *p->counter << ": How are you doing?" << endl;
        return (NULL);
}

void *answer(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "Mary from node " << p->id << ", sleeping for " << delay << " milliseconds." << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Mary from node " << p->id << " , to Henry from node " << *p->counter << ": I am very busy today!" << endl;
        return(NULL);
}

void *reply(void *arg)
{
        parm *p=(parm *)arg;
        int delay = rand() % 10;
        cout << "Joe from node " << p->id << ", sleeping for " << delay << endl;
        sleep(delay);
        *p->counter += 1;
        cout << "Joe from node " << p->id << ", to Sam from node " << *p->counter << ": Ya, me too." << endl;
        return (NULL);
}

int main(int argc, char* argv[]) {
        int n,i;
        int counter;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;

        if (argc != 2)
        {
                cout << "Usage: "<< argv[0] << " n" << endl << "  where n is no. of threads" << endl;
                return 1;
        }

        n=atoi(argv[1]);

        if ((n < 1) || (n > MAX_THREAD))
        {
                cout << "The no of thread should between 1 and " << MAX_THREAD << "." << endl;
                return 1;
        }

        threads= new pthread_t[n]();
        pthread_attr_init(&pthread_custom_attr);

        /* Start up thread */
        p = new parm[n]();
        counter = 0;

        for (i=0; i<n; i++)
        {
                p[i].counter = &counter;
                p[i].id=i;
                if (i%2 == 0) //even numbers 0,2,4
                pthread_create(&threads[i], &pthread_custom_attr, question, (void *)&p[i]);
                else //odd number
                pthread_create(&threads[i], &pthread_custom_attr, answer, (void *)&p[i]);
                if (i%3 == 0)
                pthread_create(&threads[i], &pthread_custom_attr, question, (void *)&p[i]);
                else
                pthread_create(&threads[i], &pthread_custom_attr, reply, (void *)&p[i]);

        }

        /* Synchronize the completion of each thread. */

        for (i=0; i<n; i++)
        {
                pthread_join(threads[i],NULL);
        }
        delete threads;
        delete p;
        return 0;
}

and my output is :

-bash-3.00$ ./Thread1 2
Joe from node 0, sleeping for 3 milliseconds.
Joe from node 0, sleeping for 6 milliseconds.
Mary from node 1, sleeping for 7 milliseconds.
Joe from node 1, sleeping for 5
Joe from node 0, to Sam from node 1: How are you doing?
Joe from node 1, to Sam from node 2: Ya, me too.
Joe from node 0, to Sam from node 3: How are you doing?

I added *reply (Ya, me too.),  but it does not show up in the output. Why?
0
 

Author Comment

by:shahrine99
ID: 18112187
i mean i don't see the *answer (I am very busy today!)
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 18113607
>>>>  but it does not show up in the output. Why?

You need to let your threads running infinitely. Look at your main thread. It creates all threads in a (quick) loop ... and terminates. That will stop some of the threads that didn't get scheduled so far (maybe cause they were sleeping).

I would suggest to use only one thread function that does the questioning and the answering. If some of the threads were only asking and others do only reply it won't become a real chat.

First you need to keep your main thread running after job creation. The most easiest is to wait for user input in a while loop after creating threads:

#include <string>
   
     ...

     std:: string input;
     while (true)
     {
        cout << "Do you wan't to quit? ";
        cin >> input;
        if (input == "y" || input == "Y")
            break;
     }


Then put some more members to parm struct

struct parm
{
      ...
      std::string name;              // it's for Joe , Sam and Mary
      bool reply;                        // controls whether to ask or reply
 };


Add a new struct like

struct threadparm
{
     parm** parms;
     int         numthreads;
     int         curid;
     bool stopped;                    // controls whether to break infinite loop
};

Then replace your thread functions by something like that:


void* threadFunc(void *arg)
{
        threadparm* tp =(threadparm *)arg;
        parm*           from = (parm*) tp->parms[tp->curid];
        while (!tp->stopped)    // the stopped member can be set by the main thread to terminate  all threads
        {
             cout << from->name << "from node " << from->id << endl;
             int r = rand()%tp->numthreads;   // get some buddy to send the message to
             parm* to = tp->parms[r];
             cout << ", to " << to->name << "from node " << to->id << ": ";
             if (from->reply)
             {
                    cout <<  reply_messages[rand()%MAX_REPLYS] << endl;
                    from->reply = false;
                    to->reply = true;
             }
             else
             {
                    cout <<  question_messages[rand()%MAX_QUESTIONS] << endl;
                    from->reply = false;
                    to->reply = true;
             }

             sleep(rand()%5000000);   // sleep up to 5 seconds to give other threads a chance
         }
         return NULL;
    }
}

For reply and question messages add some global arrays at the top like

#define MAX_REPLY  10;
const char* reply_messages[MAX_REPLY] = { "Yes, I am fine", "I don't know you", "I know you very well, but I won't talk to you", ... };

Don't forget to initialize the new parm members. For thread creation you need

   threadparm tp;
   tp.parms = p;
   tp.numthreads = n;
   tp->stopped = false;

   for (i = 0; i < n; ++i)
   {
        ...
        p[i]->name = names[rand()%MAX_NAME];   // use a global name array same as with messages
        p[i]->reply  = false;

        tp.curid = i;
        pthread_create(&threads[i], &pthread_custom_attr, threadfunc, (void *)&threadparm);

   }


Regards, Alex
0
 

Author Comment

by:shahrine99
ID: 18154747
thanks alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18154925
You are welcome.

Does it work?

Note there is a critical statement what needed to get changed:

>>>>   parm*           from = (parm*) tp->parms[tp->curid];

Here the thread got it's current id no from an instance of struct threadparam. However, the thread function runs asynchronously. So, tp->curid might have changed when the thread function was scheduled what means that some of the threads would get the same id and some other ids were skipped...

To get it fixed you should pass a copy of threadparam struct to the threads rather than passing the single instance what is a matter of change in the creating loop.

Regards, Alex
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now