Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a C program with multiple threads in the background when it requires user input

I've made a fairly simple C program to compute the terms of Fibonacci sequence, which I'm running on Ubuntu. I made some rather clumsy data structures so that it can do very large integers, but the specifics of the program aren't terribly important -- what matters is that the program can take quite a while to perform the computations.

Out of curiosity, I decided I'd like to make the program start the computation and then allow the user to input a character to see how far along the computation is. So in this case, if the program is computing the n'th term of the Fibonacci sequence and it isn't done yet, inputting the number '1' will get the program to output the term k that it is currently computing. I've attempted to do that using the following approach.

The program uses scanf to get a long integer which represents the term of the sequence that needs to be computed. The program then creates a thread with the routine that I wrote to compute and print the n'th Fibonacci term, which exits once it has finished doing that. Following that, the program creates an integer variable i used to store input and initialises it so some non-zero value. It then continuously enters a while loop so long as that int is non-zero, and in each iteration of the loop it performs a scanf("%d", &i). It then compares that value to 1, and if it's 1 then it'll print the value of a counter that I've set up to track the progress of the Fibonacci computation.

Anyway, all of the above works very smoothly despite my being terribly out of depth with things like threads. However, the problem that I'm having is that when I have to compute, say, the millionth term of the sequence the program takes several minutes to finish, and it would be nice to simply run it in the background. However, if I put the process in the background with ctrl+z and then type bg, the process starts but immediately stops again. I'm guessing that this is because it is constantly requiring input from the user and thus it stops until it gets that input.

Any suggestions for how to circumvent the above issue would be greatly appreciated. I'm not especially worried about this specific issue (computation of the Fibonacci numbers) since that's just a fairly random problem I chose to use for the computation. I'm more interested in the general problem of creating a basic way for the user to input commands to the program, which the program then executes in separate threads, but which still enables the user to run the program in the background if necessary.

Apologies for the rather long-winded question, and thanks in advance for any help!

Phil

Edit: By request, I added (a very simplified version of) the code here. The basic idea is the same: the program launches a lengthy computation in a new thread, then loops for input with scanf. Inputting 0 quits the program, inputting 1 displays a counter indicating the progress of the computation. I'd like to be able to run the program in the background, but since it's continuously asking for input it stops the process immediately. Ignore the arithmetic overflow on the counter; my actual program has data structures to deal with this kind of stuff but I tried to simplify my code as much as possible for readability.

//Simple program to test threading and input.
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 2

void *stuff();
int counter; //keeps track of the progress of the computation

int main(){
  counter=1;
  pthread_t threads[NUM_THREADS];
  pthread_create(&threads[0], NULL, stuff, NULL);

  //loop while the input is non-zero so that the program can
  //accept commands
  int input=10;
  while(input){
    input=10;
    printf("Enter 0 to exit or 1 to display progress: ");
    scanf("%d", &input);
    if(input==1){
      printf("Currently iterating for the %dth time.\n", counter);
    }
  }

return 0;
}

//Randomly chosen computation that takes a while.
void *stuff(){
  long i,j,n=1000000000;
  for(i=0; i<=n; i++){
    for(j=0; j<=n; j++){
      i*i*i*i*i*i*i*i*i*i*i;
      j*j*j*j*j*j*j*j*j*j*j;
      counter++;
    }
  }
  printf("Done.\n");
  pthread_exit(NULL);
}
like image 947
ptmx Avatar asked Feb 10 '11 00:02

ptmx


People also ask

Does C allow multi threading?

C does not contain any built-in support for multithreaded applications. Instead, it relies entirely upon the operating system to provide this feature. This tutorial assumes that you are working on Linux OS and we are going to write multi-threaded C program using POSIX.

What can happen if two threads execute the same code in the program?

Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.

Can you make multiple thread to execute same instructions?

In the same multithreaded process in a shared-memory multiprocessor environment, each thread in the process can run concurrently on a separate processor, resulting in parallel execution, which is true simultaneous execution.

Why would we want to use multiple threads in our application?

What Is Multithreading Used For? The main reason for incorporating threads into an application is to improve its performance. Performance can be expressed in multiple ways: A web server will utilize multiple threads to simultaneous process requests for data at the same time.


1 Answers

Assuming that you're using POSIX Threads, you can scanf in one thread, let it block until something is entered, and then pthread_cond_signal the other thread to do whatever you want it to do. You can also declare a variable which is updated by the calculating thread and read by the thread with scanf in it. Another more sophisticated way is to listen on a socket for incoming messages, and have a message interpreter part which reads from that socket, and writes back the results. In that case you don't need the scanf, and your program can be running in background.

like image 151
Peyman Avatar answered Sep 28 '22 12:09

Peyman