Learning2code
Learning2code

Reputation: 51

Running thread simultaneously with program in C

I would like to run my thread simultaneously as my main program. How do I do so? Currently the thread is running a never ending loop, but i would like it to run at the same time as when my main program continues running. Here is my code.

This is my thread:

void *LEDReadingsTimer(char *buffer, int clientSocket) //void *arg
{
    while(timer!=0)
    {
        delay(2000);
        LEDReadings(buffer, clientSocket);
        printf("Data Sent to Android!\n");
    }
    return 0;
}

Here is my main code:

timer=1;
  wiringPiSetupSys () ;
  gertboardAnalogSetup (100) ;
  pthread_create(&tid, NULL, LEDReadingsTimer(buffer,clientSocket), NULL);


  //Receive and send data from and to Android
  while(1){ 
      nread = recv(clientSocket,buffer,4096,0);//recvfrom(clientSocket, buffer,1024, 0, (struct sockaddr *) &serverStorage, &addr_size);
      buffer[nread] = '\0';

      if((atof(buffer)>=0)&&(atof(buffer)<=1)){
      printf("Data Received: %s\n", buffer);  
      LEDBrightness(buffer);             
      //LEDReadings(buffer, clientSocket);

  } 

This is my LEDReadings function.

int LEDReadings(char *buffer, int clientSocket){
    int x1, x2 ;
    double v1, v2 ;
    double a;

    printf ("| Channel 0 | Channel 1 |\n") ;
        // Read the 2 channels:
        x1 = analogRead (100) ; //voltage
        x2 = analogRead (101) ; //current
        // Convert to a voltage:
        v1 = (double)x1 / 1023.0 * 3.3 ;
        v2 = (double)x2 / 1023.0 * 3.3 ;
        a = v2*30;
        printf ("%6.3f|%6.3f\n", v1, a) ;
        fflush (stdout) ;
        snprintf(buffer, 4096,"%6.3fsplit%6.3f\n", v1, a);
        send(clientSocket,buffer,strlen(buffer)+1,0);
        return 0;
}

Once my pthread runs, it doesn't go into the next while loop to do recv function.

Upvotes: 0

Views: 1303

Answers (2)

Sami Kuhmonen
Sami Kuhmonen

Reputation: 31143

You are calling the thread function yourself rather than giving it to pthread_create as a pointer. This means the function will run forever and no thread will ever be created.

You need to create a way to pass parameters, for example a struct

struct params
{
    char *buffer;
    int clientSocket;
}

Then you change your thread function into one that gets it as a parameter

void *LEDReadingsTimer(void *args)
{
    struct params *pars = args;

    while(timer!=0)
    {
        delay(2000);
        LEDReadings(pars->buffer, pars->clientSocket);
        printf("Data Sent to Android!\n");
    }

    return 0;
}

And in your main function you define a struct, set values and pass it to the thread funtion through pthread_create;

struct params pars;
pars.buffer = buffer;
pars.clientSocket = clientSocket;

pthread_create(&tid, NULL, LEDReadingsTimer, &pars);

This way your thread function is called by pthread and the parameters you pass to it will be usable from the thread. Of course always make sure the parameter struct doesn't go out of scope and get freed while the thread is running.

Upvotes: 1

user2371524
user2371524

Reputation:

I assume you know you have to pass pthread_create() a function pointer. There's no such thing in C as a "function pointer with arguments", it's just the address of the function. So what you do here is just call a function the normal way, this function never returns, so the pthread_create() is never executed, waiting for evaluation of one of its arguments.

Have a look at the prototype of pthread_create():

   int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);

This means your start_routine must accept and return void *. So you have to change the signature of your function to

void *LEDReadingsTimer(void *args);

Now, how do you pass the parameters? Simply use a struct. Define this struct somewhere:

struct LEDReadingsTimerArgs
{
    char *buffer;
    int clientSocket;
};

Then you can change your thread function to this:

void *LEDReadingsTimer(void *args)
{
    struct LEDReadingsTimerArgs *lrtArgs = args;
    while(timer!=0)
    {
        delay(2000);
        LEDReadings(lrtArgs->buffer, lrtArgs->clientSocket);
        printf("Data Sent to Android!\n");
    }
    return 0;
}

The last argument of pthread_create is for passing the arguments, so start your thread like this:

struct LEDReadingsTimerArgs lrtArgs = {buffer, clientSocket};
pthread_create(&tid, NULL, LEDReadingsTimer, &lrtArgs);

Upvotes: 1

Related Questions