C: Having a global variable why the value is not saved when it is called in main function, - c

I'm new to C programming. In my main.c file I declare a global variable and initialize it to 0. This variable will run in pthread function and there it should be updated so I can reuse it main function again.
static int gResult = 0;
void* pthreadTask(){
gResult= readValue(); // It gives 1. gResult should be 1 now.
// But it gives 0.
}
int main(){
if(gResult == 1)printf("Passed test");
}

The problem looks like is that the thread is created but it is not scheduled immediately. So, the thread doesn't run any code and before that you check the value of your global variable. Try checking the variable after your thread has finished running. So, check the variable after pthread_join(). Do not use pthread_exit(). Try the following code (I tried it and it works):
#include <stdio.h>
#include <pthread.h>
static int gRes0 = 0;
static void *pthreadTask5(void* ctx)
{
gRes0 = 1;
printf("Value of gRes0 in thread = %d\n", gRes0);
}
int main(void)
{
pthread_t pt;
pthread_create(&pt, NULL, pthreadTask5, NULL);
// join pthread.
pthread_join(pt, NULL);
printf("Value of gRes0 in main = %d\n", gRes0);
return 0;
}

Related

C : pthread : value doesn't stay same in thread parameter

I try to test Linux pthread. I create multithread, in each thread, I pass some parameters through thread_arg struct. Before I pass to thread function, I print out, everything works fine. When this parameter passes to thread function, I print out again, I see that value in parameters doesn't stay as before.
Here is my code :
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
typedef struct {
int paramA;
int paramB;
} thread_arg;
void* message(void* argObj) {
thread_arg* arg = (thread_arg*) argObj;
printf("Test2: %d &&& %d\n", arg->paramA, arg->paramB);
return NULL;
}
void Func(int id, int num) {
// run num-th thread.
int i;
for (i = 1; i <= num; i++) {
// start a new thread
pthread_t thread;
// printf("thread with: %d and %d\n", id, i);
// thread_arg arg = {.studentId = id, .questionId = i};
thread_arg arg;
arg.paramA = id;
arg.paramB = i;
printf("test 1: %d &&& %d\n", arg.paramA, arg.paramB);
pthread_create(&thread, NULL, &message, &arg);
}
}
int main() {
int i;
for(i=0;i<1;i++) {
Func(i, 3);
}
while (1);
return 0;
}
The result is :
test 1: 0 &&& 1 // normal
test 1: 0 &&& 2 // normal
test 1: 0 &&& 3 // normal
Test2: 0 &&& 3 // strange error
Test2: 0 &&& 3 // strange error
Test2: 0 &&& 3 // strange error
It's so strange, because three lines on test 2 should be contains all number 1 2 and 3.
I cannot explain why this situation happen. Please explain for me.
Thanks :)
When you create a new thread with pthread_create(), you pass the address of the arguments as &arg. This is just a pointer, and a pointer is all that your thread receives. When your Func() code loops around to start another thread, your arg variable goes out of scope and is destroyed. The memory previously occupied by arg is used for something else (probably the arg created for the next iteration of the loop).
One way to solve this is to allocate thread_arg *parg = (thread_arg *) malloc(sizeof thread_arg); and pass parg (a pointer) to pthread_create(). Don't forget to free the arguments within the thread after you're done with them.

User level thread

I am trying to create user level thread. Here is a sample of my code. Can any body help me what is the problem in this program.
#include<stdio.h>
#include<ucontext.h>
int thread_counter = 0;
int thread1, thread2;
int who_am_i;
struct TCB {
ucontext_t context;
void (* fun_ptr)();
};
struct TCB tcb[3];
char stack[2][8192];
//----------------------
int thread_create(void (*fun)()) {
static volatile int s;
thread_counter++;
s = 0;
getcontext(&tcb[thread_counter].context);
if(!s) {
tcb[thread_counter].context.uc_stack.ss_sp = stack[thread_counter];
tcb[thread_counter].context.uc_stack.ss_size = sizeof(stack[thread_counter]);
tcb[thread_counter].context.uc_link = &tcb[0].context;
tcb[thread_counter].fun_ptr = fun;
s = 1;
}
else {
tcb[who_am_i].fun_ptr();
}
return thread_counter;
}
void thread_yield(int next_thread) {
static volatile int switched;
switched = 0;
getcontext(&tcb[who_am_i].context);
if(!switched) {
switched = 1;
who_am_i = next_thread;
setcontext(&tcb[next_thread].context);
}
}
//----------------------
void f1() {
printf("start f1\n");
thread_yield(thread2);
printf("finish f1:\n");
}
void f2() {
printf("start f2\n");
thread_yield(thread1);
printf("finish f2\n");
}
//----------------------
int main() {
thread1 = thread_create(f1);
thread2 = thread_create(f2);
who_am_i = 0;
thread_yield(thread1);
return 0;
}
Thread is not switching properly. When I run it, it gives following output:
start f1
start f2
finish f2
Thank you
You have an undefined behavior situation.
In thread_create you increase thread_counter the first thing you do. So when you create the second thread thread_counter will be 2. Then you access stack[2] which will give you undefined behavior.
You also hardcode the uc_link member of the context to &tcb[0].context, which is never initialized due to your "premature" increment of thread_counter.
But the main problem is that you don't actually create a new context, you just get the context for the current thread. You should use makecontext for each thread instead.

How to stop a specific thread in C process.h?

I just learn the bare bone of making a thread inside a program using process.h in C programming. And now, my problem is how to stop a specific thread.
Here is my code:
#include <stdio.h>
#include <windows.h>
#include <process.h>
void mimicCounter( void * );
int main()
{
int i;
printf( "Now in the main() function.\n" );
_beginthread( mimicCounter, 0, (void*)12 );
for(i = 2; i <= 10; i++){
Sleep(500);
printf("%d\n",i);
}
system("PAUSE");
printf("\n");
}
void mimicCounter( void *arg )
{
int i;
printf( "The mimicCounter() function was passed %d\n", (INT_PTR)arg ) ;
for(i = 1; i <= 10; i++){
Sleep(500);
printf("%d\n",i);
}
}
I just want to stop the thread that I have created (the mimicCounter function) when it reaches i = 5, (yeah I know I set it to 10 but this is for ending a thread demo).
Thank you so much :)
The _endthread and _endthreadex functions terminate a thread created by _beginthread or _beginthreadex, respectively. You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter to _beginthread or _beginthreadex. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.
From http://msdn.microsoft.com/en-us/library/aa246804(v=vs.60).aspx

C - pthread function reuse - local variables and race conditions

If I define a thread function that reuses another function that the main thread also uses....is it possible that there can be a race condition? Are the local variables in the same function shared across threads? In this case the function do_work is used in both the thread_one thread and the main thread. Can the local variable x in the function do_work be modified by both threads so it creates an unexpected result?
void *thread_one() {
int x = 0;
int result;
while(1) {
for(x=0; x<10; x++) {
result = do_work(x);
}
printf("THREAD: result: %i\n", result);
}
}
int do_work(int x) {
x = x + 5;
return x;
}
int main(int argc, char**argv) {
pthread_t the_thread;
if( (rc1 = pthread_create( &the_thread, NULL, thread_one, NULL)) ) {
printf("failed to create thread %i\n", rc1);
exit(1);
}
int i = 0;
int result = 0;
while(1) {
for(i=0; i<12; i+=2) {
result = do_work(i);
}
printf("MAIN: result %i\n", result);
}
return 0;
}
No. Local variables aren't shared across threads.
No, local variables of thread are not shared accross threads.
In detail, each thread has its own set of registers and stack. However, code and global data are shared.
No since x is a local variable. Every thread works with his own x variable, so there's no possibility for a thread to modify other thread's x.
No, and the more important point is that local (automatic) variables are not shared between multiple instances of a function even in the same thread. This is how recursion works and what makes it possible for functions to be reentrant.

Multithreading - C - Duplicate Static Variable

is there anyway to duplicate some static variable each time a thread make access to them?
I post a simple example:
Module testF.c
#define <stdio.h>
#include <windows.h>
#include <process.h>
#include "testF.h"
#define MAX_THREADS 10
int *var;
void testF( void *arg ){
int a,N,i;
a = (INT_PTR)arg;
N = (int)(10000/(int)(a+1));
var = (int*) malloc(N*sizeof(int));
for(i = 0; i<N; i++)
var[i] = (int)a;
_endthread();
}
...
And in another module main.c,
...
#include "testF.h"
int main(void){
HANDLE hth[MAX_THREADS];
DWORD dwExitCode;
int i;
for(i = 0; i<MAX_THREADS; i++)
hth[i] = (HANDLE)_beginthread( testF, 0, (void*)i );
WaitForMultipleObjects(MAX_THREADS, hth, TRUE, INFINITE);
for(i = 0; i<MAX_THREADS; i++){
GetExitCodeThread( hth[i], &dwExitCode );
printf( "thread 1 exited with code %u\n", dwExitCode );
CloseHandle( hth[i] );
}
}
In the this example the variable i would like to duplicate is *var.
I've seen that functions like rand() give always the same result if called from different thread, so I think that there should be a way to do it.
Thread-local storage.
Functions like rand() generally use thread local storage to maintain intercall state on a per-thread basis. This is what you would need to do instead of using a language construct like static. Your other option is to supply the variable into the thread start function, instead of using a global or static.

Resources