cstringmultithreading

C Thread Access Global Variable


So, I've been working on a socket messaging project on my free time, and I have not been able to get past the problem of the user's input erasing every time a new message is printed. I'm trying to avoid ncurses because it doesn't do well with threads. How can I get thread_function to access the string variable (thread_function is just a function I've been using to test how the program would perform when messages are printed in a thread, as they will be when the socket programs are implemented)? Here's some relevant code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>

char *string;

int thread_function(void *) {
  while (1) {
    sleep(1);
    printf("\n\e[1F\e[2K%s\n> %s", "Hello, world!", (char *) string);
    fflush(stdout);
  }
  return 0;
}

int main(int argc, char **argv) {
  thrd_t thread;
  thrd_create(&thread, thread_function, NULL);
  string = malloc(2);
  char character;
  int position;
  while (1) {
    printf("> ");
    memset(string, 0, 2);
    character = 0;
    position = 0;
    while (1) {
      character = getchar();
      if (character == '\n') break;
      string = realloc(string, position + 1);
      string[position++] = character;
    }
    string[position] = '\0';
    printf("\e[1F\e[2K%s\n", string);
  }
  free(string);
  thrd_join(thread, 0);
}

I've tried thread mutexes and atomic variables and locks, as well as making the string variable volatile. I've also tried passing a pointer to the string variable to the thread as an argument.


Solution

  • None of the problems have anything to do with multi-threading. This is all fundamental string handling bugs, as explained at How should character arrays be used as strings? and Common string handling pitfalls in C programming.

    Bugs:

    One easy fix is to keep track of the allocated size by malloc/realloc in a separate variable rather than relying on string length.

    Note that sizeof(char) is always 1 so x * sizeof(char) is just bloat guaranteed to be equivalent to x * 1.