Cuong Hoang Van Cuong Hoang Van - 25 days ago 8
Linux Question

2 thread parallel in linux

I just begin to implement thread. I want create 1 main thread and 2 thread running parallel.
This is my code:

#include <stdio.h>
#include <pthread.h>
#include <glib.h>
#include <time.h>

#define THREAD1 1
#define THREAD2 2

GMainLoop *loop1;
GMainLoop *loop2;

pthread_t pth1; // this is our thread identifier
pthread_t pth2; // this is our thread identifier

gboolean timeout_callback1(gpointer data){
clock_t start = clock();
int msec = start * 1000 / CLOCKS_PER_SEC;
printf("timeout_callback ==== 1 at %d seconds %d milliseconds\n", msec/1000, msec%1000);
}

gboolean timeout_callback2(gpointer data){
sleep(2);
clock_t start = clock();
int msec = start * 1000 / CLOCKS_PER_SEC;
printf("timeout_callback ==== 2 at %d seconds %d milliseconds\n", msec/1000, msec%1000);
}

/* This is our thread function. It is like main(), but for a thread */
void *threadFunc(void *arg)
{
int *index;
int i = 0;

index=(int*)arg;

if (index == THREAD1){
printf("threadFunc: %d\n", index);
loop1 = g_main_loop_new ( NULL , FALSE );
//add source to default context
g_timeout_add (100 , timeout_callback1 , loop1);
g_main_loop_run (loop1);
g_main_loop_unref(loop1);
} else {
if (index == THREAD2){
printf("threadFunc: %d\n", index);
loop2 = g_main_loop_new ( NULL , FALSE );
//add source to default context
g_timeout_add (100 , timeout_callback2 , loop2);
g_main_loop_run (loop2);
g_main_loop_unref(loop2);
}else
printf("index not support\n");
}

return NULL;
}

int main(void)
{
int i = 0;
/* Create worker thread */
pthread_create(&pth1,NULL,threadFunc,THREAD1);
pthread_create(&pth2,NULL,threadFunc,THREAD2);

/* wait for our thread to finish before continuing */

while(1)
{
usleep(1);
//printf("main() is running...\n");
//++i;
}

return 0;
}


command build:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include thread.c -o thread -lglib-2.0 -lpthread


result:

threadFunc: 2
threadFunc: 1
timeout_callback ==== 1 at 0 seconds 2 milliseconds
timeout_callback ==== 2 at 0 seconds 72 milliseconds
timeout_callback ==== 1 at 0 seconds 72 milliseconds
timeout_callback ==== 2 at 0 seconds 142 milliseconds
timeout_callback ==== 1 at 0 seconds 142 milliseconds
timeout_callback ==== 2 at 0 seconds 218 milliseconds
timeout_callback ==== 1 at 0 seconds 218 milliseconds
timeout_callback ==== 2 at 0 seconds 283 milliseconds
timeout_callback ==== 1 at 0 seconds 283 milliseconds
timeout_callback ==== 2 at 0 seconds 348 milliseconds
timeout_callback ==== 1 at 0 seconds 348 milliseconds
timeout_callback ==== 2 at 0 seconds 421 milliseconds


this result is'n like as my expect. I think timeout_callback1 is called more times timeout_callback2 because in fucntion timeout_callback2 has sleep(2);

Could you help me explain for me about result?
And Pleas give me some advice how to timeout_callback1 run with independence timeout_callback2 ?

Thank you so much.

Answer

If you read g_timeout_add documentation here: https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add you can find that:

This internally creates a main loop source using g_timeout_source_new() and attaches it to the global GMainContext

And from GMainContex here:https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GMainContext

The GMainContext struct is an opaque data type representing a set of sources to be handled in a main loop.

And furthermore:

GMainContext can only be running in a single thread, but sources can be added to it and removed from it from other threads.

Therefore it actually makes sense since both the THREAD1 and THREAD2 will be calling g_timeout_add() at the same rate.