Executing threads in 'paralelism' - c

I have a range of number (i.e 1~10000).
I need to create threads to search for a value X.
Each thread will have your own interval to search for it (i.e 10000/threadNumber).
I guess there is no meaning to make the threads run in sequence. I'm having problem to make they run concurrently...
My Code so far:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define limit 10000
#define n_threads 2
void* func1(void* arg)
{
int i=0, *value = (int *)arg;
//How may I know which thread is running and make the thread search for the right range of values ?
for(i=1; i<=limit/n_threads; i++)
{
if(*value == i){
//Print the thread ID and the value found.
}
else
//Print the thread ID and the value 0.
}
return NULL;
}
int main(int argc, char const *argv[])
{
if(argc < 2)
printf("Please, informe the value you want to search...\n");
else{
pthread_t t1, t2;
int x = atoi(argv[1]); //Value to search
pthread_create(&t1, NULL, func1, (void *)(&x));
pthread_create(&t2, NULL, func1, (void *)(&x));
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
return 0;
}
Problems so far:
I don't know how to find thread ID. (tried with pthread_self() but I always get a giant negaative number so I think something is wrong.
I know that pthread_create() creates and initialize the thread, also the pthread_join will make my main program to wait for the thread. But Looking into my code it doesn't seems to be runing concurrently.
How my threadX will know from what range of values it's suppose to start searching ? (i.e: If I have 10 threads, I don't think I'll have to create 10 functions o.O ).
is it possible to make them run concurrently without something like Mutex ?

Getting the thread id varies according to your operating system.
See how to get thread id of a pthread in linux c program? as #user3078414 mentioned, and why compiler says ‘pthread_getthreadid_np’ was not declared in this scope?.
Credits to #Dmitri, an example of passing multiple values to the thread function. The threads run concurrently. Mutexes is a whole other chapter that deals with shared data and how you access it.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define limit 10000
#define n_threads 2
struct targs {
int from;
int to;
};
void *func1(void *arg) {
struct targs *args = (struct targs *) arg;
printf("%d => %d\n", args->from, args->to);
// free(arg)
return NULL;
}
int main(int argc, char const *argv[]) {
struct targs *args;
pthread_t t1;
pthread_t t2;
args = (struct targs *) malloc(sizeof(args));
args->from = 0;
args->to = 100;
pthread_create(&t1, NULL, func1, (void *) args);
args = (struct targs *) malloc(sizeof(args));
args->from = 100;
args->to = 200;
pthread_create(&t2, NULL, func1, (void *) args);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}

Related

Thread that creates new threads till some threads count

I'm learning POSIX threads. The goal is to write program, that creates one thread, which creates two new threads. Every created thread spawns two further threads. Every new thread should sleep, than tells his id(sleep time and ID it becomes as parameter), computing overall sleeping time then starts to create new threads.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define MAX_THREADS 10
pthread_mutex_t wait_time_overall_mutex;
pthread_mutex_t threads_count_mutex;
pthread_mutex_t struct_mutex;
int wait_time_overall = 0;
int threads_count = 0;
struct threads_data {
int thread_id;
int time;
};
void* SpawnTwoThreads(void *args) {
pthread_t t1;
pthread_t t2;
struct threads_data t_args = *(struct threads_data*)args;
int this_thread_id = t_args.thread_id;
int this_time = t_args.time;
printf("t%d: Sleeping for %d\n", this_thread_id, this_time);
sleep(this_time);
pthread_mutex_lock(&wait_time_overall_mutex);
wait_time_overall = wait_time_overall + this_time;
pthread_mutex_unlock(&wait_time_overall_mutex);
printf("My id is: %d\n", this_thread_id);
if (threads_count < MAX_THREADS) {
pthread_mutex_lock(&threads_count_mutex);
threads_count++;
pthread_mutex_unlock(&threads_count_mutex);
pthread_mutex_lock(&struct_mutex);
t_args.time = rand() % 10;
t_args.thread_id = threads_count;
pthread_mutex_unlock(&struct_mutex);
pthread_create(&t1, NULL, SpawnTwoThreads, &t_args);
}
if (threads_count< MAX_THREADS) {
pthread_mutex_lock(&threads_count_mutex);
threads_count++;
pthread_mutex_unlock(&threads_count_mutex);
pthread_mutex_lock(&struct_mutex);
t_args.time = rand() % 10;
t_args.time = threads_count;
pthread_mutex_unlock(&struct_mutex);
pthread_create(&t2, NULL, SpawnTwoThreads, &t_args);
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Bye from %d\n", this_thread_id);
pthread_exit(NULL);
}
int main(void) {
pthread_t t1;
int t1_wait_time;
srand(time(NULL));
pthread_mutex_init(&threads_count_mutex, NULL);
pthread_mutex_init(&wait_time_overall_mutex, NULL);
pthread_mutex_init(&struct_mutex, NULL);
struct threads_data args;
args.thread_id = threads_count++;
args.time = rand() % 10;
pthread_create(&t1, NULL, SpawnTwoThreads, &args);
printf("In main: waiting for all threads to complete\n");
pthread_join(t1, NULL);
printf("Overall waittime is %d\n", wait_time_overall);
pthread_exit(NULL);
}
It creates all threads that i want, but id doesn't unique. I'm becoming output like this:
My id is 0
My id is 2
My id is 2
My id is 4
My id is 4
It shouldn't be sorted. But at least should be every id unique. Did I done some mistake with mutex? Before creation of new thread I'm updating struct variables. But it doesn't look like that.

How to join/detach/clean dynamic malloc threads that are created per function call?

I wrote a sample code of my problem. In the while loop, I am dynamically creating new threads per function call, which will be processed in the calculate function. This could potentially take several seconds to finish and I used sleep to simulate this.
How do I clean these threads? They have separate threads with their own stack of args, so would it be possible to clean them in the calculate function at the end per call? But then I would run into the problem of some threads still calculating when the condition of random == 2 is met and the program exits.
I'm thinking of a variable that would change state when the calculation has finished, but still have the same problem as described above. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
struct args_struct {
pthread_t pt;
int random;
};
void* calculate(void *arguments){
struct args_struct *args = arguments;
sleep(args->random);
printf("Number: %d. %s", args->random, "Calculations completed, thanks for waiting!");
}
int main(){
while(1){
struct args_struct *args = malloc(sizeof (struct args_struct));
time_t t;
srand((unsigned) time(&t));
args->random = rand() % 5;
if(pthread_create( &args->pt, NULL, calculate, (void *)&args) != 0)
printf("Error in creating thread!");
if (args->random == 2 ){ //random condition in exiting loop
printf("Number is %d. Exiting program and joining remainder threads still running...", args->random);
//pthread_join? free(args)? pthread_exit? pthread_detach?
//pthread_join(args->pt, NULL);
//free(args);
return 0;
};
}
}
Argument args of pthread_create() is wrong.
Try change (void *)&args -> (void *)args.
Default stdout stream buffering is line buffering(_IOLBF).
Try insert '\n' character to printf() function.
Create seed(srand function) only once.
Finally, try the following.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
struct args_struct {
pthread_t pt;
int random;
};
void* calculate(void *arguments){
struct args_struct *args = arguments;
sleep(args->random);
printf("Number: %d. %s\n", args->random, "Calculations completed, thanks for waiting!");
if (args->random != 2) free(args);
}
int main(){
time_t t;
srand((unsigned) time(&t));
while(1){
struct args_struct *args = malloc(sizeof (struct args_struct));
args->random = rand() % 5;
if(pthread_create( &args->pt, NULL, calculate, (void *)args) != 0)
printf("Error in creating thread!\n");
if (args->random == 2 ){ //random condition in exiting loop
printf("Number is %d. Exiting program and joining remainder threads still running...\n", args->random);
pthread_join(args->pt, NULL);
free(args);
return 0;
};
}
}

In C, how do I pass variables to functions in Pthreads upon thread creation?

Working from this example:
https://computing.llnl.gov/tutorials/pthreads/samples/hello.c
I've worked backwards and tried to edit in what I'm hoping to accomplish.
I'd like to pass data to the thread being spawned.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid;
tid = (long)depth;
printf("This is where things get done.\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
I see on line:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
My function Entropy gets called here, so I thought I'd try to tack on some brackets and pass a variable to that function the way I'd seen it done before. This seems to be a little different though, since this whole line returns something to rc, I wonder if that changes how I pass data to my thread, but I'm not sure how else I'd do it.
Right now this code compiles and runs, int main() goes fine without a hitch but it seg faults the moment it tries to create new threads.
In order to pass data to a thread you need to prepare the data in some place in memory, and pass a pointer to that place into pthread_create. It is pthread_create's job to pass that pointer to the runner function of your thread:
typedef struct {
long tid;
int depth;
}thread_data;
...
void *Entropy(void *dataPtr) {
thread_data *data= (thread_data*)dataPtr;
printf("This is where things get done for %li.\n", data->tid);
pthread_exit(NULL);
}
...
pthread_t threads[NUM_THREADS];
thread_data data[NUM_THREADS];
...
for(t=0;t<NUM_THREADS;t++) {
data[t].tid = t;
data[t].depth = depth;
rc = pthread_create(&threads[t], NULL, Entropy, (void *)&data[t]);
}
Your code crashes since you pass incorrect parameters:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
// ^^^^^^^^^^^^^^
Here you should pass function pointer void *(*)(void *) but you are passing void *, and moreover value is unspecified since Entropy() has no return statement (did you turn warnings on at all?). I guess it should be like this:
rc = pthread_create(&threads[t], NULL, Entropy, (void *)t);
Next, how to pass parameter to thread routine? Technically you can use any pointer, but you should think twice about what you are passing. First of all pointed data must be valid when new thread runs. I.e. you shouldn't pass addresses of any locals except if you are sure that thread is finished when you are leaving scope of passed data - use pthread_join(new_thread) at the scope end to achieve that. Another approach is to pass pointer to data at global scope, that is surely valid at any moment. But there is one flaw - such data are visible to all threads, so you may accidentally make a mess. To avoid it - use dynamic memory - allocate data block with malloc() pass pointer to thread and free it in that thread. Latter option reduces chances to corrupt someone's else data.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid = *((long *)depth);
free(depth);
printf("This is where things get done.\n", tid);
return NULL;
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
long *arg = malloc(sizeof(*arg));
*arg = t;
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy, arg);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0;t<NUM_THREADS;t++){
pthread_join(threads[t], NULL);
}
}

UNIX Pthreads & mutex; program locks up

Following scenario:
We are supposed to make x Threads maximum. Our main-function is supposed to make a single new thread with a pointer to the function 'makeThreads'. This function is supposed to make up to 2 threads, depending on how many threads are already there. Race conditions are to avoid.
I'm stuck. I'm not exactly sure how to solve the problem I'm running into, partly because I don't can't identify the problem itself.
Suggestions are greatly appreciated!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#define MAX_THR 20
pthread_mutex_t mutex;
int threadCount = 0;
int randomNbr(){
int number = (rand() % 10) + 1;
return number;
}
void *makeThreads(void* number){
int rndnmb = *((int *) number);
pthread_mutex_lock(&mutex);
sleep(rndnmb);
pthread_t threadDummy;
int thread1, i, threadID, rndnbr;
threadID = threadCount;
printf("Hello from Thread %d!\n", threadID);
for(i = 0; i < 2; i++){
if(threadCount < MAX_THR){
rndnbr = randomNbr();
int *rnd = &rndnbr;
threadCount++;
thread1 = pthread_create(&threadDummy, NULL, *makeThreads, (void *) rnd);
pthread_join(threadDummy, NULL);
}
}
pthread_mutex_unlock(&mutex);
printf("Goodbye from Thread %d!\n", threadID);
}
int main(){
int t1, rndnbr;
pthread_t threadOne;
pthread_mutex_init(&mutex, NULL);
srand(time(NULL));
rndnbr = randomNbr();
int *rnd = &rndnbr;
threadCount++;
t1 = pthread_create(&threadOne, NULL, *makeThreads, (void *) rnd);
pthread_join(threadOne, NULL);
}

multithreading in C: passing a structure

I am learning multithreading performance in C. When I tried to write a sample code, I bumped into a problem:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
typedef struct{
int a;
char b;
} args;
void* some_func (void* arg)
{
args *argsa = malloc(sizeof(args));
//copy the content of arg to argsa,
//so changes to arg in main would not affect argsa
*argsa = *(args*) arg;
int i = 10;
for (; i > 0; i--)
{
usleep (1); //to give other threads chances to cut in
printf ("This is from the thread %d\n", argsa->a);
}
free (argsa);
}
int main()
{
pthread_t thread[3];
args ss;
int index = 0;
ss.b = 's';
for (; index <3 ; index++)
{
ss.a = index;
if (pthread_create (thread+index, NULL, some_func, (void*)&ss ))
{
usleep(10);
printf ("something is wrong creating the thread");
}
}
pthread_join ( thread[0], NULL);
pthread_join ( thread[1], NULL);
pthread_join ( thread[2], NULL);
return 0;
}
I know char b in the struct is useless, but I just want to practice passing a structure.
I expect the code to print out "This is from the thread x", where x is 0, 1 or 2, alternatively. However, the code currently only gives me "This is from the thread 2" 30 times. I believe there is something wrong with
*argsa = *(args*) arg;
But I can't find a way to solve this and get the desired output.
Any help would be appreciated!
Because you are passing the same pointer to all the threads. By the time thread 0 has started, you have already incremented the value of ss.a to 1 (and then 2).
This is a bit more correct:
void* some_func (void* arg)
{
args *argsa = (args*)arg;
int i;
for (i = 0; i < 10; i++)
{
usleep (1); //to give other threads chances to cut in
printf ("This is from the thread %d\n", argsa->a);
}
}
int main()
{
pthread_t thread[3];
args ss[3];
int index;
for (index = 0; index < 3; index++)
{
ss[index].a = index;
if (pthread_create(&thread[index], NULL, some_func, &ss[index] ))
{
printf ("something is wrong creating the thread");
}
}
pthread_join ( thread[0], NULL);
pthread_join ( thread[1], NULL);
pthread_join ( thread[2], NULL);
return 0;
}
The pattern to use to solve this kind of problem is as follows:
Create a structure that will hold the parameters you want to pass to the thread.
Allocate such a structure with malloc.
Fill in the structure.
Pass the pointer to the structure to the thread.
When the thread is finished with the structure, the thread frees it.
This assumes you don't need to get any information back from the thread. If you do, you can change it so that the code that joins the thread frees the structure. That allows the structure to hold a reply as well -- you join the thread, read the response information, and then free the structure.
No special locking or synchronization is required because while the newly-created thread exists, it is the only thread that touches the structure.
Sorry guys, but I was trying to solve the same issue and I don't think a proper answer was given yet, in order to solve the problem. I tried this on my own and I came up with the following code. Now, I compiled and run it and it pretty worked as I expected, still I not that confident that the "lock in main and unlock in child process" is the most elegant solution, so I'd like to know what you think about it. Thank you very much in advance for any clarification.
Here is the code:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
typedef struct{
int a;
char b;
} args;
pthread_mutex_t lock;
void* some_func (void *arg) {
args argsa = *(args*)arg;
pthread_mutex_unlock(&lock);
printf ("This is from the thread %d\n", argsa.a);
}
int main() {
pthread_t thread[10];
args ss;
int i, index=0;
ss.b = 's';
if (pthread_mutex_init(&lock, NULL) != 0) {
printf("\n mutex init failed\n");
return 1;
}
for (index = 0; index < 10 ; index++)
{
pthread_mutex_lock(&lock);
ss.a = index;
printf("index=%d, ", ss.a);
if (pthread_create (thread+index, NULL, some_func, (void*)&ss ))
{
usleep(10);
printf ("something is wrong creating the thread");
}
}
for(i=0;i<10;i++)
pthread_join ( thread[0], NULL);
return 0;
}
Output:
#./program
index=0, This is from the thread 0
index=1, This is from the thread 1
index=2, This is from the thread 2
index=3, This is from the thread 3
index=4, This is from the thread 4
index=5, This is from the thread 5
index=6, This is from the thread 6
index=7, This is from the thread 7
index=8, This is from the thread 8
index=9, This is from the thread 9

Resources