Running two or more functions simultaneously? - c

In C, is it possible to run multiple functions at the same time? At least 2 is what I need to run simultaneously. For example:
void menu() {
/* Provides some kind of menu with scanf */
}
void printMsg() {
while(1) {
printf("Hello World...");
sleep(60);
}
}
Is there a way to run printMsg() while also being able to interact with the menu?

Related

How to interrupt sleep() without using multiple threads in C?

I'm writing a terminal application for Linux which uses the ncurses library to update the terminal with a 1 second sleep in between each update. I want to keep this sleeping behaviour, but at the same time I want the program to exit immediately when I hit the q-key, not getting a potential 1 second lag. Therefore I need a way to interrupt sleep(). I am aware that alarm() will do that for me, but for that I need another thread which calls alarm(). This does not mix well with ncurses which is single-threaded. Is there anything that might help me achieve this?
My code is something like this:
void run() {
while (1) {
for (int i = 0; i < num_things; ++i) {
if (getch() == 'q') return;
printw("Something");
refresh();
}
sleep(1);
}
}
Thanks to #Barmar. Use ncurses timeout(1000) before getch(). Like this:
void run() {
while (1) {
for (int i = 0; i < num_things; ++i) {
printw("Something");
refresh();
}
timeout(1000);
if (getch() == 'q') return;
}
}

GUI using GTK in C is not displaying real-time values being fed in

I am trying to build a GUI application for an activity monitor in C, and decided to use GTK library along with Glade to help with the design. (Using Ubuntu 20.04)
Upon pressing the button, values are displayed in the respective positions and are updated upon every click.
The only problem is I need it to update by itself in real-time, so I shifted the code into an infinite loop with sleep(1), so it updates them after every 1 second. But values are not even being displayed on the GUI now.
To test if the code is even being executed, I tried printing values on the console from different parts of the code, and they are indeed being printed.
Things I've tried, but didn't work:
Switching between loops and recursions, both failed.
Replacing the sleep() function with a self-made timer using time.h library
Encapsulate the GUI-displaying code into a function, and have that whole function called in a loop.
Forcing the refresh on GUI using GDK functions, so it updates the GUI manually in every iteration.
Used gtk_show_all in different parts of the code to force it to display at the end of every iteration.
I think it has to do with the button trigger, and output is only updated on the GUI after the callback function is executed (from my observation with console prints).
So I am trying to have the button programmatically pressed in intervals, to avoid having to click it myself every time, but could not find much on the topic.
If you can think of any way to make this work or an alternative to the approach I am taking, kindly help out.
The main idea is that the output GUI should have values updated in real-time, regardless of the button.
Thanks in advance!
This is the function used to print out the values on the GUI:
struct timespec tm;
tm.tv_sec = 0;
tm.tv_nsec = 1000 * 1000 * 1000;
myproc_t* myprocs = NULL;
unsigned int myprocs_len = 0;
//call to function that will return the processes and their specifications
sample_processes(&myprocs, &myprocs_len, tm);
if(s == 0){
// sort by CPU usage
qsort(myprocs, myprocs_len, sizeof(myprocs[0]), myproc_comp_pcpu);
}
else if(s == 1){
// sort by Memory usage
qsort(myprocs, myprocs_len, sizeof(myprocs[0]), myproc_comp_rss);
}
for (i = 0; i < myprocs_len && i < 5; i++)
{
if (strlen(myprocs[i].cmd) == 0) {
break;
}
//convert specs read from /proc file to string format
sprintf(pid, "%d", myprocs[i].tid);
sprintf(cpu, "%.2f",myprocs[i].pcpu);
sprintf(memory, "%lu", myprocs[i].vm_rss/1000);
sprintf(cmd, "%s", myprocs[i].cmd);
switch(i)
{
case 0:
gtk_label_set_text(GTK_LABEL(PID1), pid);
gtk_label_set_text(GTK_LABEL(CPU1), cpu);
gtk_label_set_text(GTK_LABEL(MEM1), memory);
gtk_label_set_text(GTK_LABEL(CMD1), cmd);
case 1:
gtk_label_set_text(GTK_LABEL(PID2), pid);
gtk_label_set_text(GTK_LABEL(CPU2), cpu);
gtk_label_set_text(GTK_LABEL(MEM2), memory);
gtk_label_set_text(GTK_LABEL(CMD2), cmd);
case 2:
gtk_label_set_text(GTK_LABEL(PID3), pid);
gtk_label_set_text(GTK_LABEL(CPU3), cpu);
gtk_label_set_text(GTK_LABEL(MEM3), memory);
gtk_label_set_text(GTK_LABEL(CMD3), cmd);
case 3:
gtk_label_set_text(GTK_LABEL(PID4), pid);
gtk_label_set_text(GTK_LABEL(CPU4), cpu);
gtk_label_set_text(GTK_LABEL(MEM4), memory);
gtk_label_set_text(GTK_LABEL(CMD4), cmd);
case 4:
gtk_label_set_text(GTK_LABEL(PID5), pid);
gtk_label_set_text(GTK_LABEL(CPU5), cpu);
gtk_label_set_text(GTK_LABEL(MEM5), memory);
gtk_label_set_text(GTK_LABEL(CMD5), cmd);
}
}
Using a loop with sleep(1) or anything that blocks is always a no-go, since that means you're effectively blocking the UI thread from doing any actual work. The normal workflow is the following:
You want to have a main loop running, either by using gtk_main() or gtk_application_new() and connecting to the "activate" signal (which will be called when you call gtk_application_run()).
Initialize your backend code
Initialize your UI code, in which you create the necessary widgets for each process. At this point, you probably already want to make it visible using gtk_widget_show() and friends
For the periodic updates, you should post a periodic event to the main loop, which you can using API like g_timeout_add_seconds (). In the callback you can call gtk_label_set_text() on the labels you created in the previous step. As long as the callback returns G_SOURCE_CONTINUE, the callback will keep being called periodically at the specified interval
To expand on what #nielsdg correctly said, UI code based on event loop (such as GTK) must limit the blocking code to the bare minimum.
/* Never do this: it will freeze the UI */
static void
on_button_clicked()
{
do {
/* Your code here */
sleep(1);
while (condition);
}
Instead, unroll your code and leverage the main event loop:
static gboolean
iteration(gpointer user_data)
{
/* Your code here */
return condition ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
}
static void
on_button_clicked()
{
g_timeout_add(1000, iteration, NULL);
}
This just gives you the main idea. The code above has some problems, above all if you click twice it will happily start two cooperative loops.

Making this simple code threadsafe

I have just had a really good use for multithreading. As such.... I have to learn multithreading. I have a very simple program:
void *listenloop(void *arg){
while (1){
Sleep(2000);
puts("testing 123\n");
}
return NULL;
}
int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){
puts("Scanning: ");
scanf("%s",testinput);
puts("\n\n");
printf("You typed: %s: ",testinput);
}
}
The theory is that it waits for user input, echos it, all while periodically printing.
None to my surprise, actually (and presumably obviously to my betters in the matter) the output is "messed up."
Now I can think of several ways around this problem, but no actual solutions. How should something of this nature be implemented? Can it just be done by manipulating the output of the program after it is displayed to the user?
Thanks!
So just wrap the prints in pthread_mutex_lock/unlocks with a single pthread_mutex_t and you should be fine.
http://linux.die.net/man/3/pthread_mutex_lock
pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER;
void *listenloop(void *arg){
while (1){
Sleep(2000);
pthread_mutex_lock(&mutex);
puts("testing 123\n");
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){
pthread_mutex_lock(&mutex);
puts("Scanning: ");
pthread_mutex_unlock(&mutex);
scanf("%s",testinput);
pthread_mutex_lock(&mutex);
puts("\n\n");
printf("You typed: %s: ",testinput);
pthread_mutex_unlock(&mutex);
}
}
In your original code, there should be no "messed up" output (caused by threading, anyway) in that code as only the one thread (the main one) is doing any output.
The only thing the other thread does is infinitely loop with a delay of some sort.
Now that you've updated the question to output from the other thread then, yes, it is possible for the output to intermix.
There are several ways around this, two spring to mind immediately.
Have all output go through a series of functions which mutex-protect the output stream, such as mutexed_printf()/mutexed_puts() (which you'll need to provide) (a).
Do all output from one of the threads, meaning the other will have to send data to it via some means (inter-thread communications like a queue) - that way all output can be properly mixed, such as on newline boundaries.
(a) Also keep in mind that, if you want to mutex protect the output stream for the user input operation, you'll probably want to protect the puts/scanf atomically so that the testing output doesn't mess up your input (by outputting messages after the prompt but before/during your input). That won't be possible with a mutexed_puts() function, you'll need an expanded mutexed_prompt_and_input() one.

Using a global variable to control a while loop in a separate thread

gcc (GCC) 4.6.3
c89
valgrind-3.6.1
Hello,
Updated code snippet
+++++++++++++++++++++++++++++++++++
void *thread_recv_fd()
{
pthread_mutex_lock(&mutex_queue);
while(start_receiving) {
pthread_mutex_unlock(&mutex_queue);
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
using the above locks looks very ugly now. And I am still getting a race error on the reading of the start_receiving. I have also declared it as volatile as well.
+++++++++++++++++++++++++++++++++++++
I am running a while loop in a worker thread that polls every 1/2 second. I control it with a global variable start_receiving after the user enters ctrl-c it will change the value to false.
Having a global like this is it good practice?
The reason I asked as I get these 2 errors when I run helgrind:
==6814== Possible data race during write of size 4 at 0x601958 by thread #1
==6814== at 0x401131: main (driver.c:78)
==6814== This conflicts with a previous read of size 4 by thread #2
==6814== at 0x4012A7: thread_recv_fd (driver.c:127)
This are the lines of code:
driver.c:78 is this line of code start_receiving = FALSE;
driver.c:127 is this line of code while(start_receiving) in the while loop
Source code, just the important snippets:
static int start_receiving = FALSE;
int main(void)
{
pthread_t thread_recv_id;
pthread_attr_t thread_attr;
/* Start polling as soon as thread has been created */
start_receiving = TRUE;
do {
/* Start thread that will send a message */
if(pthread_create(&thread_recv_id, &thread_attr, thread_recv_fd, NULL) == -1) {
fprintf(stderr, "Failed to create thread, reason [ %s ]",
strerror(errno));
break;
}
}
while(0);
/* Wait for ctrl-c */
pause();
/* Stop polling - exit while loop */
start_receiving = FALSE;
/* Clean up threading properties */
pthread_join(thread_recv_id, NULL);
pthread_exit(NULL);
}
void *thread_recv_fd()
{
while(start_receiving) {
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
Many thanks for any suggestions,
No, it's very bad practice.
At the very least, the variable should be volatile to avoid being optimized out.
You should really look into using some real multi-thread primitives for this though, such as mutexes (to protect the shared state, so that the two threads aren't accessing it at the same time) and atomic variables (to make sure the state is thread-proof).
Polling isn't a right way.
I suggest you to read about conditional variables
You could use atomics, but the simplest solution here is just to use locking around the controlling variable. For example:
static int start_receiving = FALSE;
static pthread_mutex_t start_receiving_lock = PTHREAD_MUTEX_INITIALIZER;
int is_receiving(void)
{
int r;
pthread_mutex_lock(&start_receiving_lock);
r = start_receiving;
pthread_mutex_unlock(&start_receiving_lock);
return r;
}
Then in the thread function:
void *thread_recv_fd()
{
while(is_receiving()) {
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
..and in the main function:
pthread_mutex_lock(&start_receiving_lock);
start_receiving = 1;
pthread_mutex_unlock(&start_receiving_lock);

How to call function with infinite-loop?

I need help to clear my concepts.
I have a function which toggle the Led status on/off after every second. Now the code for the on/off runs inside infite loop.
Example:
void ToggleLed( int pin_number)
{
// some code
while(1)
{
// code to execute the Led status
}
}
Now when I integrate this code with base line and called that function inside other function it just doesnt work no other functionality of software works.
Question: Function has infinite-loop and that it doesn't come out of control and other functions called after that function doesn't work.
If that is the case do I need to provide separate thread to it?
Any suggestion will be helpful.
Yes you will need a separate thread, or some other form of asynchronous execution. Once you enter that while loop, no other code runs in that thread. Ever.
If I understand correcctly nothing works in your integrated version. In that case, yes you probably need to run the infinite loop on a separate thread, because your function with the infinit loop will never exit, so no other code will ever run on that thread.
You don't say what OS, but yes, set it as a low-priority thread, minimal stack size. I flash a LED in my projects, just so I can easily see if the code has reached the abort-handler yet :)
void LEDflash_task_code(void *p)
{
while (1)
{
FIO1CLR=STATUS_LED;
OSsleep(750);
FIO1SET=STATUS_LED;
OSsleep(250);
};
};
If you have access to hardware peripheral timers (any micrcontroller/microprocessor application), you should use those hardware timers, not threads nor software sleep().
void init_toggle_led (uint32_t interval)
{
setup_hardware_timer(interval);
}
void toggle_led (void)
{
if( (hardware_timer_register & flag) > 0 )
{
port = port ^ pin_mask;
}
}
main()
{
init_toggle_led(1000);
for(;;)
{
do_stuff();
toggle_led();
}
}
This was an example with polling. Alternatively, you can use hardware interrupts from the timers and toggle the port from there.
As David mentioned, you should run your LED code in a separate thread. http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#BASICS
Once you have threads, if you want your code to be able to stop your LED from blinking, then add a flag that's checked inside the while loop at each iteration, and if it's set then break out.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * toggle_led(void *ptr);
int stop=0;
int main (int argc, const char * argv[])
{
printf("Hello, World!\n");
// set up thread
pthread_t LED_thread;
char * message = "blink!";
pthread_create( &LED_thread, NULL, toggle_led, (void*) message);
// do some other work
sleep(5);
// ok you want to quit now
stop=1;
pthread_join(LED_thread, NULL);
printf("Goodbye!\n");
return 0;
}
void *toggle_led(void *ptr)
{
while (!stop)
{
printf("%s \n", (char *)ptr);
sleep(1);
}
}
I think you need to implement as a watchdog functionality. Because if you use threads then even if other threads has some issues(like deadlock), your LEDs will toggle as long as toggle_led thread works. You need to implement an toggle_led() function and call from each of other threads /functions before returning to make sure all other threads/functions are getting executed successfully without waiting continuously for some resources

Resources