Multithreading - C - Duplicate Static Variable - c

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.

Related

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

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;
}

Some threads never get execution when invoked in large amount

Consider the following program,
static long count = 0;
void thread()
{
printf("%d\n",++count);
}
int main()
{
pthread_t t;
sigset_t set;
int i,limit = 30000;
struct rlimit rlim;
getrlimit(RLIMIT_NPROC, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_NPROC, &rlim);
for(i=0; i<limit; i++) {
if(pthread_create(&t,NULL,(void *(*)(void*))thread, NULL) != 0) {
printf("thread creation failed\n");
return -1;
}
}
sigemptyset(&set);
sigsuspend(&set);
return 0;
}
This program is expected to print 1 to 30000. But it some times prints 29945, 29999, 29959, etc. Why this is happening?
Because count isn't atomic, so you have a race condition both in the increment and in the subsequent print.
The instruction you need is atomic_fetch_add, to increment the counter and avoid the race condition. The example on cppreference illustrates the exact problem you laid out.
Your example can be made to work with just a minor adjustment:
#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <pthread.h>
#include <stdatomic.h>
static atomic_long count = 1;
void * thread(void *data)
{
printf("%ld\n", atomic_fetch_add(&count, 1));
return NULL;
}
int main()
{
pthread_t t;
sigset_t set;
int i,limit = 30000;
struct rlimit rlim;
getrlimit(RLIMIT_NPROC, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_NPROC, &rlim);
for(i=0; i<limit; i++) {
if(pthread_create(&t, NULL, thread, NULL) != 0) {
printf("thread creation failed\n");
return -1;
}
}
sigemptyset(&set);
sigsuspend(&set);
return 0;
}
I made a handful of other changes, such as fixing the thread function signature and using the correct printf format for printing longs. But the atomic issue is why you weren't printing all the numbers you expected.
Why this is happening?
Because you have a data race (undefined behavior).
In particular, this statement:
printf("%d\n",++count);
modifies a global (shared) variable without any locking. Since the ++ does not atomically increment it, it's quite possible for multiple threads to read the same value (say 1234), increment it, and store the updated value in parallel, resulting in 1235 being printed repeatedly (two or more times), and one or more of the increments being lost.
A typical solution is to either use mutex to avoid the data race, or (rarely) an atomic variable (which guarantees atomic increment). Beware: atomic variables are quite hard to get right. You are not ready to use them yet.

How to make thread safe program?

On a 64-bit architecture pc, the next program should return the result 1.350948.
But it is not thread safe and every time I run it gives (obviously) a different result.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <pthread.h>
const unsigned int ndiv = 1000;
double res = 0;
struct xval{
double x;
};
// Integrate exp(x^2 + y^2) over the unit circle on the
// first quadrant.
void* sum_function(void*);
void* sum_function(void* args){
unsigned int j;
double y = 0;
double localres = 0;
double x = ((struct xval*)args)->x;
for(j = 0; (x*x)+(y*y) < 1; y = (++j)*(1/(double)ndiv)){
localres += exp((x*x)+(y*y));
}
// Globla variable:
res += (localres/(double)(ndiv*ndiv));
// This is not thread safe!
// mutex? futex? lock? semaphore? other?
}
int main(void){
unsigned int i;
double x = 0;
pthread_t thr[ndiv];
struct xval* xvarray;
if((xvarray = calloc(ndiv, sizeof(struct xval))) == NULL){
exit(EXIT_FAILURE);
}
for(i = 0; x < 1; x = (++i)*(1/(double)ndiv)){
xvarray[i].x = x;
pthread_create(&thr[i], NULL, &sum_function, &xvarray[i]);
// Should check return value.
}
for(i = 0; i < ndiv; i++){
pthread_join(thr[i], NULL);
// If
// pthread_join(thr[i], &retval);
// res += *((double*)retval) <-?
// there would be no problem.
}
printf("The integral of exp(x^2 + y^2) over the unit circle on\n\
the first quadrant is: %f\n", res);
return 0;
}
How can it be thread safe?
NOTE: I know that 1000 threads is not a good way to solve this problem, but I really really want to know how to write thread-safe c programs.
Compile the above program with
gcc ./integral0.c -lpthread -lm -o integral
pthread_mutex_lock(&my_mutex);
// code to make thread safe
pthread_mutex_unlock(&my_mutex);
Declare my_mutex either as a global variable like pthread_mutex_t my_mutex;. Or initialize in code using pthread_mutex_t my_mutex; pthread_mutex_init(&my_mutex, NULL);. Also don't forget to include #include <pthread.h> and link your program with -lpthread when compiling.
The question (in a comment in the code):
// mutex? futex? lock? semaphore? other?
Answer: mutex.
See pthread_mutex_init, pthread_mutex_lock, and pthread_mutex_unlock.

Thread Programming... No output in terminal

I m doing thread programming and trying to implement MonteCarlo technique for calculating Pi value in it. I compiled the code and I have no error but when I execute I get no output for it. Kindly correct me if there's any mistake.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define frand() ((double) rand() / (RAND_MAX))
#define MAX_LEN 1353
const size_t N = 4;
float circlePoints=0;
void* point_counter(void *param){
float xcord;
float ycord;
while(MAX_LEN){
xcord=frand();
ycord=frand();
float cord = (xcord*xcord) + (ycord*ycord);
if(cord <= 1){
circlePoints++;}
}
}
int main()
{
printf("out");
size_t i;
pthread_t thread[N];
srand(time(NULL));
for( i=0;i <4;++i){
printf("in creating thread");
pthread_create( &thread[i], NULL, &point_counter, NULL);
}
for(i=0;i <4;++i){
printf("in joining thread");
pthread_join( thread[i], NULL );
}
for( i=0;i <4;++i){
printf("in last thread");
float pi = 4.0 * (float)circlePoints /MAX_LEN;
printf("pi is %2.4f: \n", pi);
}
return 0;
}
You're hitting an infinite loop here:
while(MAX_LEN){
Since MAX_LEN is and remains non-zero.
As to why you see no output before that, see Why does printf not flush after the call unless a newline is in the format string?
You have an infinite loop in your thread function:
while(MAX_LEN){
...
}
So all the threads you create never come out that loop.
Also, circlePoints is modified by all the threads which will lead to race condition ( what's a race condition? ) and likely render the value incorrect. You should use a mutex lock to avoid it.
while(any_non_zero_number_which does_not_update)
{
infinite loop //not good unless you intend it that way
}

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

Resources