Search code examples
ctcppthreadsclientbuffer

pthreads fill buffer in unexpected way


I am trying to fill a buffer using pthreads in a simple TCP/IP server client communication.

ATTENTION: Client writes its contents to an external server-address (not mine) and server reads its contents from an external client. The client and server that I have put below, do not communicate with each other.

The buffer is filled in two ways:

  1. Server reads a message and puts it into the buffer
  2. Client creates a message and puts it into the buffer

Here is the client function:

void *client(void *threadid)
{
  //CLIENT INITIALIZATION AND CONNECT TO SERVER PROPERLY
  //sleep(1);   //sleep 1 second before you send again
  char *buff = "message1";   //message1,2,3 etc is defined by a random function

  pthread_mutex_lock(&lock);

  write(sockfd, buff, strlen(buff)+1);

  buffer_fill(buff);
  pthread_mutex_unlock(&lock);
  }
  pthread_exit(NULL);
 }

And here is the server function. Server reads from an external device that runs the same client code with me:

void *server(void *threadid)
{
  //SERVER INITIALIZATION USING THE PROPER PORT AND ADDRESS
  pthread_mutex_lock(&lock);
  bzero(buff, MAX_LENGTH);
  // read the message from client and copy it in buffer
  while(strlen(buff) == 0){
    read(sockfd, buff, sizeof(buff));
  }
  buffer_fill(buff);
  pthread_mutex_unlock(&lock);
  }
  pthread_exit(NULL);
}

I am using a simple pthread initialization in my main function. So I am calling each function through the utilization of a thread:

int main(int argc, char **argv)
{

  pthread_t threads[NUM_THREADS];
  int rc[NUM_THREADS];
  long t;

  for(t=0; t<NUM_THREADS; t++){

    //initiallize thread
    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        printf("\n mutex init failed\n");
        return 1;
    }


    //create each thread according to value of t
    if(t==0){
      rc[t] = pthread_create(&threads[t], NULL, server, (void *)t);
    }else if(t==1){
      rc[t] = pthread_create(&threads[t], NULL, client, (void *)t);
    }

  }

  pthread_join(tid[0], NULL);
  pthread_join(tid[1], NULL);
  pthread_mutex_destroy(&lock);

  /* Last thing that main() should do */
  pthread_exit(NULL);

  return 0;
}

I assume the problem lies somewhere in the use of the (extremely simple) buffer_fill(char *message) in combination with the threads (note : msg is a global variable initialized to zero outside main, int msg = 0):

void buffer_fill(char *m){

  if (msg<=MAX_MESSAGES){
    buffer[msg] = m;
    msg ++;
  }
  print_buffer();
}

When I execute this code continuously I get that kind of result:

first print:
message2

second print:
message1
message1

third print:
message5
message5
message5

and so on.

  • Note that messages[1:5] are been selected randomly by the client and do not affect the outcome
  • I assure you that the server client set up is correct. I checked it before writing the code that fills the buffer

Why is it that messages print like that and not in a serial form? I want every random message that is going to be written by client and every message that is read by the server to be stacked on buffer one after the other like this:

first print:
message2

second print:
message2
message1

third print:
message2
message1
message5

Solution

  • you problem happens here

    void buffer_fill(char *m){
    
      if (msg<=MAX_MESSAGES){
        buffer[msg] = m; // where
        msg ++;
      }
      print_buffer();
    }
    

    you should copy the value to buffer from m using strcpy or using a loop.

    Edit: char * <=> const char * you should create an array or dynamically allocate the buffer.