Multi-threading


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
Top Forums Programming Multi-threading
# 1  
Multi-threading

In this piece i implemented the gossip method. The first thread is invoked from inside the
Quote:
Main()
(msg is first sent from node -1 to 0 from main()) and the other threads are invoked from inside of the thread function itself. I used two mutexes and a condition variable to control the synchronization.
One mutex is declared inside of the node structure to lock any structure properties. The second mutex, is used to lock an array of node structure. The thread function description is as follows:

Quote:
When thread function is called, it sets the properties of the node according to the parameter passed to it. like node id which sent the msg to the current node, msg content, msg_received flag ...,
Before the new node starts searching for its neighbours and send them the msg (call thread) if they haven't yet received it, the node first lock the condition variable and checks whether the message has already been sent to all neighbours of the sender's neighbours or not. This way, i make sure redundant threads are not called.

Code:

#include<iostream>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<list>
#include<pthread.h>
#include<cstring>
using namespace std;

static int round;
#define checkResults(string, val){    \
   if(val){    \
       printf("failed with %d at %s", val, string);    \
       exit(1);    \
   }    \
}    \

#define _NODES 8

typedef struct{      // thread parameter
  int id;
  int rcvd_from;
  string msg;
}thread_param_t;

struct node          // node structure 
{
   pthread_mutex_t f_lock;
   thread_param_t  packet;
   vector<int> edges;
   bool msg_received;
} nodes[_NODES];

pthread_t callThd[_NODES];    //keeps track of all thread IDs
pthread_mutex_t list_lock;    //locks the array nodes[], which stores node structures
pthread_mutex_t path_mutex;   //locks the path array--we don't need it as we always read the path
pthread_cond_t  next_round_ready = PTHREAD_COND_INITIALIZER;  //statically initializing a condition variable-- it assures the message is sent
// to all other sender's neighbours before one of the neighbours tries to find it's surrounding neighbours


bool msg_sent_to_all(int , int );  // it looks whether the message is sent to all sender's surrounding neighbours

//---------------
int path[_NODES][_NODES] = {
      { 0, 1, 1, 1, 0, 0, 0, 0 },
      { 1, 0, 0, 1, 1, 0, 0, 0 },
      { 1, 0, 0, 1, 0, 1, 0, 0 },
      { 1, 1, 1, 0, 1, 0, 0, 0 },
      { 0, 1, 0, 1, 0, 1, 0, 1 },
      { 0, 0, 1, 0, 1, 0, 1, 1 },
      { 0, 0, 0, 0, 0, 1, 0, 1 },
      { 0, 0, 0, 0, 1, 1, 1, 0 }
                                 }; // keeps the sparse graph
//---------------

void *funcThd(void *arg)   //Thread function, the argument is the structure defined above (thread_param..)
{
   cout << "void *funcThd(void *arg)\n";

   pthread_attr_t attr;
   string message;
   int index, rc, received_from, neighbours_size;
   pthread_t tid;

  rc = pthread_attr_init(&attr);
      checkResults("pthread_attr_init()\n", rc);
  rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // setting detached as our thread attributes, this way none of the calling threads
//expect the caller thread to wait for them-- so, no need for pthread_join(..)
      checkResults("pthread_attr_setdetachstate()\n", rc);

   thread_param_t *p = (thread_param_t *) arg;  //store the message properties temporarily
               index = p -> id;    
             message = p -> msg;
       received_from = p -> rcvd_from;

   printf("Thread %d Activated by %d\n", index, received_from);
  //pthread_mutex_lock(&path_mutex); we don need to lock the path as we always read it

  pthread_mutex_lock(&list_lock);           //lock the list of nodes
  pthread_mutex_lock(&nodes[index].f_lock); //lock the particular node in which the message has been sent to, this lock exists in every node structure
  
  nodes[index].msg_received = true;      //node got the message
  nodes[index].packet.id    = index;     //index of the node
  nodes[index].packet.msg   = message;   //message content
  neighbours_size = nodes[received_from].edges.size();   //number of neighbours staying adjacent to the node 

  printf("Message Delivered to %d from %d : ", index, received_from); 
  cout << message << endl;

 //for optimality, for each round the calling threads are not gonna start finding their neighbouring nodes BEFORE the message is sent to all
//the neighbours of the calling threads, for example is message is sent from 0 to 1, 1 is not gonna send the message to its neighbours 1, 3, 4
 // before 0 sends the message to all its neighbours first 1, 3, 5 -- so, we wouldn't have redundant threads

  while(msg_sent_to_all(received_from, neighbours_size) == false && received_from != 0)
    pthread_cond_wait(&next_round_ready, &list_lock);   
//the condition variable is locked by the node list mutex, it will then automaticly get unlocked whenever the condition satisfies
// that is when the message is sent to all the neighbours     


     for(int i = 0; i < _NODES; i++)
     {
        printf("loop %d\n", i);

         if(path[index][i])
         {
             nodes[index].edges.push_back(i);  //finding neighbours from path matrix and push them back to the nodes edge property

                if(nodes[i].msg_received == false)  // if the msg is not sent to the node, then try sending it
                {
                   p -> id = i; 
                   p -> msg = message;
                   p -> rcvd_from = index;
                   
                   printf("Sending Message to %d from %d \n", i, index);                 
                   pthread_create(&callThd[i], &attr, funcThd, (void *) p); // calling the thread
                   cout << "\n\n";
                }
         }
     }//end of for
     
  pthread_mutex_unlock(&nodes[index].f_lock);  //unlocking, node structure lock
  pthread_mutex_unlock(&list_lock);            //unlocking node list lock
  //pthread_mutex_unlock(&path_mutex);
  
  pthread_exit(NULL);

}
//-----------------
bool msg_sent_to_all(int index, int neighbours_size)  
{
   int temp;

   cout << "msg_send_to_all()..\n";   
   //pthread_mutex_lock(&list_lock);
   //pthread_mutex_lock(&nodes[index].f_lock);   
   printf("Node ID : %d  No. of neighbours : %d\n", index, neighbours_size);    

     for(int i = 0; i < neighbours_size; i++)
     {
           temp = nodes[index].edges[i];   cout << "temp =  " << temp;
               if(nodes[temp].msg_received == false)      cout << "--> " << nodes[temp].msg_received << endl;
                cout << "returning false..\n";
                  return false; 
     }
   //pthread_mutex_unlock(&list_lock);
   //pthread_mutex_unlock(&nodes[index].f_lock);
   cout << "returning true..\n";
   return true;
}
//-----------------

int main(int argc, char **argv)
{
  thread_param_t    param;
  pthread_attr_t    attr;
  pthread_t        thread;  
  int             rc = 0, detachstate;

  //START-->initializing mutexs
   if(!pthread_mutex_init(&list_lock, NULL))
            cout << "mutex_nodes initialized..\n";

   if(!pthread_mutex_init(&path_mutex, NULL))
        cout << "path_mutex initialized..\n";

       for(int index = 0; index < _NODES; index++)
               if(!pthread_mutex_init(&nodes[index].f_lock, NULL))
                    printf("nodes[%d].f_lock initialized..\n", index);
  //END-->initializing mutex

  //START-->setting thread attributes

  // create a default thread attributes object
   rc = pthread_attr_init(&attr);
   checkResults("pthread_attr_init()\n", rc);
   //set the detach state thread attribute
   rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   checkResults("pthread_attr_setdetachstate()\n", rc);
          
   //END-->setting thread attributes
  
  //Initializing the source node -- node 0

    param.id = 0;
    param.rcvd_from = -1;
    param.msg = "Purple";
    
    nodes[0].msg_received = true;
    pthread_create(&callThd[0], &attr, funcThd, (void *) &param); // starting the first round ;-)
    sleep(10);

    /*    
    for(int i = 0; i < _NODES; i++)
    {
            cout << nodes[i].msg_received << " " << nodes[i].packet.id << " " << nodes[i].packet.msg << endl;
            int cap = nodes[i].edges.size();
                    for(int j = 0;  j < cap; j++)
                    {
                        cout << nodes[0].edges[j] << "  ";
                    }
          cout << "\n";
    }
*/    
   cout << "Exiting Main()..\n"; 
   pthread_exit(NULL);

  return 0;
}

//-------------------


The output of the code is as following:

Code:

user@user-desktop:~/Desktop/gossip today$ ./a.out
mutex_nodes initialized..
path_mutex initialized..
nodes[0].f_lock initialized..
nodes[1].f_lock initialized..
nodes[2].f_lock initialized..
nodes[3].f_lock initialized..
nodes[4].f_lock initialized..
nodes[5].f_lock initialized..
nodes[6].f_lock initialized..
nodes[7].f_lock initialized..
void *funcThd(void *arg)
Thread 0 Activated by -1
Message Delivered to 0 from -1 : Purple
msg_send_to_all()..
Node ID : -1  No. of neighbours : 0
returning true..
loop 0
loop 1
Sending Message to 1 from 0 


loop 2
Sending Message to 2 from 0 
void *funcThd(void *arg)
Thread 2 Activated by 0


void *funcThd(void *arg)
Thread 2 Activated by 0
loop 3
Sending Message to 3 from 0 
void *funcThd(void *arg)
Thread 3 Activated by 0


loop 4
loop 5
loop 6
loop 7
Message Delivered to 2 from 0 : Purple
msg_send_to_all()..
Node ID : 0  No. of neighbours : 3
temp =  1--> 0
returning false..
loop 0
loop 1
loop 2
loop 3
Sending Message to 3 from 2 
void *funcThd(void *arg)
Thread 3 Activated by 2


loop 4
loop 5
Sending Message to 5 from 2 
void *funcThd(void *arg)
Thread 5 Activated by 2


loop 6
loop 7
Message Delivered to 2 from 0 : Purple
msg_send_to_all()..
Node ID : 0  No. of neighbours : 3
temp =  1--> 0
returning false..
loop 0
loop 1
loop 2
loop 3
Sending Message to 3 from 2 
void *funcThd(void *arg)
Thread 3 Activated by 2


loop 4
loop 5
Sending Message to 5 from 2 
void *funcThd(void *arg)
Thread 5 Activated by 2


loop 6
loop 7
Message Delivered to 3 from 0 : Purple
msg_send_to_all()..
Node ID : 0  No. of neighbours : 3
temp =  1--> 0
returning false..
loop 0
loop 1
Sending Message to 1 from 3 
void *funcThd(void *arg)
Thread 1 Activated by 3


loop 2
loop 3
loop 4
Sending Message to 4 from 3 
void *funcThd(void *arg)
Thread 4 Activated by 3


loop 5
loop 6
loop 7
Message Delivered to 3 from 2 : Purple
msg_send_to_all()..
Node ID : 2  No. of neighbours : 6
temp =  0returning false..
Message Delivered to 5 from 2 : Purple
msg_send_to_all()..
Node ID : 2  No. of neighbours : 6
temp =  0returning false..
Exiting Main()..



Quote:
The problem in the output is that the same thread is executed a few times, like maybe thread 3 executes 3 times, and the node is not able to find its neighbours !!!!
Any helps would be appreciable
# 2  
Checking this in more detail, but for starters you shouldn't be using cin/cout/cerr in threads. You shouldn't be mixing printf() and cout even without threads, they compete for the same resources. cout/printf also buffer for one thing, which creates more potential race conditions unless you mutex it. fprintf(stderr, ...) would be better if you must, since it's unbuffered and less likely to interrupt each other in the middle of a line. write()-ing to STDERR_FILENO would be best.

---------- Post updated at 02:35 PM ---------- Previous update was at 02:27 PM ----------

You're missing some brackets from here I think:

Code:
     for(int i = 0; i < neighbours_size; i++)
     {
           temp = nodes[index].edges[i];
           fprintf(stderr, "temp =  %d", temp);
               if(nodes[temp].msg_received == false)
               fprintf(stderr, "--> %d\n",  nodes[temp].msg_received);

                       fprintf(stderr, "returning false..\n");
                  return false;
     }

Without a code block, the if-statement only applies to the first statement below it. Meaning, no matter what the result of the if-statement is, it will always return false on the very first loop. If I infer the meaning of your code correctly, what you wanted was this:
Code:
     for(int i = 0; i < neighbours_size; i++)
     {
           temp = nodes[index].edges[i];
           fprintf(stderr, "temp =  %d", temp);
               if(nodes[temp].msg_received == false)
               {
                       fprintf(stderr, "--> %d\n",  nodes[temp].msg_received);
                       fprintf(stderr, "returning false..\n");
                       return false;
               }
     }

This User Gave Thanks to Corona688 For This Post:
# 3  
Using "fprintf( stderr, ... )" will not guarantee that the output from multiple threads won't be mixed together, since any one fprintf() call can make multiple underlying write() calls to the stderr file descriptor.

To get guaranteed non-interleaved output, you have to actually make the write() call on STDERR_FILENO yourself, as Corona688 already stated.

The easiest way to do that is to write your own code, similar to this:

Code:
int printerr( const char *fmt, ... )
{
    char buffer[ 1024 ];
    char *tmp;
    va_list ap;
    int rc;

    va_start( ap, fmt );

    tmp = buffer;
    rc = vsnprintf( tmp, sizeof( buffer ), fmt, ap );

    // must check error BEFORE casting to size_t!
    if ( rc < 0 )
    {
        va_end( ap );
        return( -1 );
    }

    if ( ( ( size_t ) rc ) >= sizeof( buffer ) )
    {
        // account for trailing nul since vsnprintf() return for too-small buffer does not
        rc++;
        // could use malloc(), but it's much slower,
        // and cleanup is much more complicated
        tmp = alloca( ( size_t ) rc );
        rc = vsnprintf( tmp, ( size_t ) rc, fmt, ap );
        if ( rc < 0 )
        {
            va_end( ap );
            return( rc );
        }
    }

    rc = ( int ) write( STDERR_FILENO, tmp, ( size_t ) strlen( tmp ) );
    va_end( ap );
    return( rc );
}

This User Gave Thanks to achenle For This Post:
# 4  
I revised my code. Now the output is:
Code:
user@user-desktop:~/Desktop/gossip$ ./a.out
mutex_nodes initialized..path_mutex initialized..nodes[0].f_lock initialized..nodes[1].f_lock initialized..nodes[2].f_lock initialized..nodes[3].f_lock initialized..nodes[4].f_lock initialized..nodes[5].f_lock initialized..nodes[6].f_lock initialized..nodes[7].f_lock initialized..thread started..Thread 0 Activated by -1
Message Delivered to 0 from -1 : returning true..loop 0
loop 1
thread started..Thread 1 Activated by 0
loop 2
thread started..Thread 2 Activated by 0
loop 3
thread started..Thread 3 Activated by 0
loop 4
loop 5
loop 6
loop 7



Quote:
Here, node 0 finds its neighbours, searches them and creates a thread for each of them. Any of them threads 1, 2 and 3 start executing, but they will wait for the mutex to get unlocked and passed to them. returning false.. here down means that each node 1 , 2 and 3 will first check whether their sender node 0 has alrady disseminated the message to all its neighbours or not (here, each node 1 , 2 and 3 will first check if 0 has already disseminated the message to its neighbours). Here, we get false, because each thread would get blocked behind a mutex and waits untill it gets unlocked. So, they can't set their msg_received flag to true earlier.
Message Delivered to 1 from 0 : returning false.. Message Delivered to 2 from 0 : returning false.. Message Delivered to 3 from 0 : returning true..loop 0 loop 1 loop 2 loop 3 loop 4 thread started..Thread 4 Activated by 3 loop 5 loop 6 loop 7 Message Delivered to 4 from 3 : returning true..loop 0 loop 1 loop 2 loop 3 loop 4 loop 5 thread started..Thread 5 Activated by 4 loop 6 loop 7 thread started..Thread 7 Activated by 4 Message Delivered to 5 from 4 : returning false.. Message Delivered to 7 from 4 : returning true..loop 0 loop 1 loop 2 loop 3 loop 4 loop 5 loop 6 thread started..Thread 6 Activated by 7 loop 7 Message Delivered to 6 from 7 : returning true..loop 0 loop 1 loop 2 loop 3 loop 4 loop 5 loop 6 loop 7 1 0 Purple 1 2 3 1 1 Purple 1 2 Purple 1 3 Purple 0 1 2 4 1 4 Purple 1 3 5 7 1 5 Purple 1 6 Purple 5 7 1 7 Purple 4 5 6 Exiting Main()..

The code is as following:
Code:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<list>
#include<pthread.h>
#include<cstring>
#include<stdarg.h>
#include<unistd.h>

using namespace std;

static int round;


#define checkResults(string, val){    \
   if(val){    \
       print("failed with %d at %s", val, string);    \
       exit(1);    \
   }    \
}    \

#define MSG_SIZE 7
#define _NODES 8

int print(const char *, ...);

typedef struct{      // thread parameter
  int id;
  int rcvd_from;
  string msg;
}thread_param_t;

struct node          // node structure 
{
   pthread_mutex_t f_lock;
   thread_param_t  packet;
   vector<int> edges;
   bool msg_received;
} nodes[_NODES];

pthread_t callThd[_NODES];    //keeps track of all thread IDs
pthread_mutex_t list_lock;    //locks the array nodes[], which stores node structures
pthread_mutex_t path_mutex;   //locks the path array--we don't need it as we always read the path
pthread_cond_t  next_round_ready = PTHREAD_COND_INITIALIZER;  //statically initializing a condition variable-- it assures the message is sent
// to all other sender's neighbours before one of the neighbours tries to find it's surrounding neighbours


bool msg_sent_to_all(int , int );  // it looks whether the message is sent to all sender's surrounding neighbours

//---------------
int path[_NODES][_NODES] = {
      { 0, 1, 1, 1, 0, 0, 0, 0 },
      { 1, 0, 0, 1, 1, 0, 0, 0 },
      { 1, 0, 0, 1, 0, 1, 0, 0 },
      { 1, 1, 1, 0, 1, 0, 0, 0 },
      { 0, 1, 0, 1, 0, 1, 0, 1 },
      { 0, 0, 1, 0, 1, 0, 1, 1 },
      { 0, 0, 0, 0, 0, 1, 0, 1 },
      { 0, 0, 0, 0, 1, 1, 1, 0 }
                                }; // keeps the sparse graph
//---------------

void *funcThd(void *arg)   //Thread function, the argument is the structure defined above (thread_param..)
{
   print("thread started..");

   pthread_attr_t attr;
   struct timespec t_req, t_rem;
   string message;
   int index, rc, received_from, neighbours_size;

   t_req.tv_sec = 1;
   t_req.tv_nsec = 500;

  rc = pthread_attr_init(&attr);
      checkResults("pthread_attr_init()\n", rc);
  rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // setting detached as our thread attributes, this way none of the calling threads
//expect the caller thread to wait for them-- so, no need for pthread_join(..)
       checkResults("pthread_attr_setdetachstate()\n", rc);

   thread_param_t *p = (thread_param_t *) arg;  
  
               index = p -> id;    
             message = p -> msg;
       received_from = p -> rcvd_from;

   print("Thread %d Activated by %d\n", index, received_from);

  //pthread_mutex_lock(&path_mutex); we don need to lock the path as we always read it

  pthread_mutex_lock(&list_lock);           //lock the list of nodes
  pthread_mutex_lock(&nodes[index].f_lock); //lock the particular node in which the message has been sent to, this lock exists in every node structure
  
  nodes[index].msg_received = true;      //node got the message
  nodes[index].packet.id    = index;     //index of the node
  nodes[index].packet.msg   = message;   //message content
  neighbours_size = nodes[received_from].edges.size();   //number of neighbours staying adjacent to the node 

  print("Message Delivered to %d from %d : ", index, received_from); 

 //for optimality, for each round the calling threads are not gonna start finding their neighbouring nodes BEFORE the message is sent to all
//the neighbours of the calling threads, for example is message is sent from 0 to 1, 1 is not gonna send the message to its neighbours 1, 3, 4
 // before 0 sends the message to all its neighbours first 1, 3, 5 -- so, we wouldn't have redundant threads

  while((msg_sent_to_all(received_from, neighbours_size) == false))
    pthread_cond_wait(&next_round_ready, &list_lock);   
//the condition variable is locked by the node list mutex, it will then automaticly get unlocked whenever the condition satisfies
// that is when the message is sent to all the neighbours     

     for(int i = 0; i < _NODES; i++)
     {
        print("loop %d\n", i);

         if(path[index][i])
         {
             nodes[index].edges.push_back(i);  //finding neighbours from path matrix and push them back to the nodes edge property

                if(nodes[i].msg_received == false)  // if the msg is not sent to the node, then try sending it
                {
                   p -> id = i; 
                   p -> msg = message;
                   p -> rcvd_from = index;
                   
                   //print("Sending Message to %d from %d \n", i, index);                 
                   pthread_create(&callThd[i], &attr, funcThd, (void *) p); // calling the thread
                   nanosleep(&t_req, &t_rem);
                }
         }
       round++;
     }//end of for
     
  pthread_mutex_unlock(&nodes[index].f_lock);  //unlocking, node structure lock
  pthread_mutex_unlock(&list_lock);            //unlocking node list lock
  //pthread_mutex_unlock(&path_mutex);
  
  pthread_exit(NULL);

}
//-----------------
bool msg_sent_to_all(int index, int neighbours_size)  
{
   int temp;

   //pthread_mutex_lock(&list_lock);
   //pthread_mutex_lock(&nodes[index].f_lock);     

     for(int i = 0; i < neighbours_size; i++)
     {
           temp = nodes[index].edges[i];  
               if(nodes[temp].msg_received == false)
                {       
                    print("returning false..\n");           
                      return false;
        } 
     }

   //pthread_mutex_unlock(&list_lock);
   //pthread_mutex_unlock(&nodes[index].f_lock);
   
   print("returning true..");

   return true;
}
//-----------------

int main(int argc, char **argv)
{
  thread_param_t    param;
  pthread_attr_t    attr;
  pthread_t        thread;  
  int             rc = 0, detachstate;

  //START-->initializing mutexs
   if(!pthread_mutex_init(&list_lock, NULL))
            print("mutex_nodes initialized..");

   if(!pthread_mutex_init(&path_mutex, NULL))
        print("path_mutex initialized..");

       for(int index = 0; index < _NODES; index++)
               if(!pthread_mutex_init(&nodes[index].f_lock, NULL))
                     print("nodes[%d].f_lock initialized..", index);
  //END-->initializing mutex

  //START-->setting thread attributes

  // create a default thread attributes object
   rc = pthread_attr_init(&attr);
   checkResults("pthread_attr_init()\n", rc);
   //set the detach state thread attribute
   rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   checkResults("pthread_attr_setdetachstate()\n", rc);
          
   //END-->setting thread attributes
  
  //Initializing the source node -- node 0

    param.id = 0;
    param.rcvd_from = -1;
    param.msg = "Purple";
    
    nodes[0].msg_received = true;
    pthread_create(&callThd[0], &attr, funcThd, (void *) &param); // starting the first round ;-)
    sleep(10);
        
    
  // cleanin up space
  pthread_cond_destroy(&next_round_ready);
  pthread_mutex_destroy(&list_lock);


  int cap = 0;

    for(int i = 0; i < _NODES; i++)
    {
                print("%d %d    ", nodes[i].msg_received, nodes[i].packet.id);
                    for(int k = 0; k < MSG_SIZE; k++)
                            print("%c", nodes[i].packet.msg[k]);  
                cap = nodes[i].edges.size();
                        for(int j = 0;  j < cap; j++)
                        {
                                            print(" %d", nodes[i].edges[j]);
                        }
          print("\n");
    }
    
   print("Exiting Main()..\n"); 
  
   exit(EXIT_SUCCESS);

  return 0;
}
//-------------------
int print(const char *ft, ...)
{
   va_list args;
  
  /* Initializing arguments to store all values after ft */
   va_start(args, ft);
   vfprintf(stderr, ft, args);
   va_end(args);
   //fprintf(stderr, "\n");
}
//-------------------


Last edited by saman_glorious; 03-18-2011 at 07:57 AM..
# 5  
Please don't PM me trying to nudge me into responding faster. Sometimes I don't answer because I really don't know.

I never did understand how pthread cond vars were supposed to work. There's no apparent way to tell the difference between success and failure.
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #487
Difficulty: Easy
A program's entry point is always defined by a main function or method.
True or False?

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Multi threading in UNIX

Hi, Can we apply multi threading in Unix. I am using bash shell. We have a generic script to load the data to table based on file input. For each file there is an individual table to load. For each file found in directory I want to load the data in parallel to target table using ... (3 Replies)
Discussion started by: vedanta
3 Replies

2. UNIX for Beginners Questions & Answers

Does UNIX support multi-Threading ?

Not just background process running ... but im looking if unix has any multi-threading concept like in Java, C# ... if not present, can you pls share the nearest feature in unix that is close to multi-threaded concept (3 Replies)
Discussion started by: i4ismail
3 Replies

3. UNIX for Dummies Questions & Answers

Confusion over Multi Threading

Hi, I am trying to get my head round Multi Threading and I have a few queries to try and clear up my confusion Q1. Is multi threading a hardware / chip level concept, an OS level or an application level concept ? I am trying to work out where SMT architecture fits in. Q2. What’s the multi... (3 Replies)
Discussion started by: jimthompson
3 Replies

4. Programming

Multi-threading

Hi, If we create 10 threads to invoke runQuery method at same time, Will queryProcessor will be overriden sometime or 10 different copies will be created? We are not using any sunchronzation mechnism in runQuery(). so there is not gurantee on QueryProcessor class variables right OR each 10... (1 Reply)
Discussion started by: jramesh1
1 Replies

5. Programming

Multi-threading-- calling same function through different threads

Sir, Can I call same function in the start routines of different Threads. I have created two different threads....and wanna call same function from both threads....is it possible??? Also can I fork inside a thread??? (1 Reply)
Discussion started by: arunchaudhary19
1 Replies

6. Programming

Multi threading?

I am not sure if multi threading is the correct term, but here is what I am trying to do. I have a while loop that displays the number 1, pauses, displays the number 2, pauses , displays the number 3 ad infinitum. It just keeps counting. While the screen displays the sequence of numbers counting... (4 Replies)
Discussion started by: enuenu
4 Replies

7. Programming

Regarding Multi-Threading

Hi All, Here's my question I have a 385 MB file containing 5,000,000 records. I need to read from the file and load into a table. Initially i thought of doing it in a single thread (execution of a single program) but when calculated accounted 16 hours of time on a standard benchmark. Hence... (5 Replies)
Discussion started by: matrixmadhan
5 Replies

8. Programming

Multi threading using fork

Hi, I have written a code which will run a set of process using fork. I want to know from You how can i start another job when one of my job in my loop is completed My code is #include<stdio.h> #include<ctype.h> main() { int pid,cid; ChildProcess(); ... (1 Reply)
Discussion started by: sureshraju_ma
1 Replies

9. Programming

Multi-threading questions

I've been doing some reading lately about threading (Posix threads) and I'm really curious about a couple things that I've read. I'm not sure if many people here have threading experience, but I thought it would be nice to be able to discuss some questions about it. (For the record, I did... (1 Reply)
Discussion started by: DreamWarrior
1 Replies

10. Programming

Multi threading using posix thread library

hi all, can anyone tell me some good site for the mutithreading tutorials, its application, and some code examples. -sushil (2 Replies)
Discussion started by: shushilmore
2 Replies

Featured Tech Videos