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.
Related
I am trying to write a simple program to understand threads. I want each thread to increment a global variable 'counter' to 4 million. Each thread only counts to 2 million. I placed a print statement at the end of each function to see how many iterations and where the global counter is at upon completion of the function. But the global counter in thread1Func is always very high, like 3.8 - 3.9 million, and then in thread2Func the counter is always 4 mil (as expected).
Am I doing this correctly? Is there a reason thread1Func is always printing such a high value for 'counter'? I would imagine it should be somewhere between 2 mil - 4 mil more evenly. Any advice would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define MAX 2000000UL
pthread_mutex_t lock;
//pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
struct shared_data
{
int value; /* shared variable to store result*/
};
struct shared_data *counter;
void* thread1Func(void * tid){
uint32_t i = 0;
while(i < MAX){
if(pthread_mutex_trylock(&lock) == 0){
counter->value++;
pthread_mutex_unlock(&lock);
i++;
}
}
printf("I am thread 1. I counted %d times. Global counter = %d\n", i, counter->value);
return NULL;
}
void* thread2Func(void * tid){
uint32_t i = 0;
while(i < MAX){
if(pthread_mutex_trylock(&lock) == 0){
counter->value++;
pthread_mutex_unlock(&lock);
i++;
}
}
printf("I am thread 2. I counted %d times. Global counter = %d\n", i, counter->value);
return NULL;
}
int main() {
counter = (struct shared_data *) malloc(sizeof(struct shared_data));
printf("Initial Counter Value: %d\n", counter->value);
pthread_t thread1;
pthread_t thread2;
pthread_mutex_init(&lock, NULL);
pthread_create(&thread1, NULL, thread1Func, NULL);
pthread_create(&thread2, NULL, thread2Func, NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
printf("Final Counter: %d\n", counter->value);
return 0;
}
the global counter in thread1Func is always very high, like 3.8 - 3.9 million, and then in thread2Func the counter is always 4 mil
That is no surprise. If both threads are working at roughly the same speed, then when the first thread finishes, the second thread should be very nearly finished too. The first thread at that point has added its two million to the global counter, and then second thread already will have added almost two million of its own. You should totally expect the global counter to be almost four million when the first thread finishes.
The only way the first thread could print two million is if the first thread is finished before the second thread has begun to work.
Fun example, good work!
Try changing the thread priorities and see what happens to see different counts (see code below).
Maybe consider adding a semaphore to ping pong the count between the 2 threads so they execute equally and report 3999999 and 4000000 as the final counts.
I am sure you have other ideas too, thanks for posting.
gcc main.c -o main
./main
Initial Counter Value: 0
I am thread 2. I counted 2000000 times. Global counter = 3880728
I am thread 1. I counted 2000000 times. Global counter = 4000000
Final Counter: 4000000
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define MAX 2000000UL
pthread_mutex_t lock;
//pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
struct shared_data
{
int value; /* shared variable to store result*/
};
struct shared_data *counter;
void* thread1Func(void * tid){
uint32_t i = 0;
while(i < MAX){
if(pthread_mutex_trylock(&lock) == 0){
counter->value++;
pthread_mutex_unlock(&lock);
i++;
}
}
printf("I am thread 1. I counted %d times. Global counter = %d\n", i, counter->value);
return NULL;
}
void* thread2Func(void * tid){
uint32_t i = 0;
while(i < MAX){
if(pthread_mutex_trylock(&lock) == 0){
counter->value++;
pthread_mutex_unlock(&lock);
i++;
}
}
printf("I am thread 2. I counted %d times. Global counter = %d\n", i, counter->value);
return NULL;
}
int main() {
counter = (struct shared_data *) malloc(sizeof(struct shared_data));
printf("Initial Counter Value: %d\n", counter->value);
pthread_t thread1;
pthread_t thread2;
pthread_mutex_init(&lock, NULL);
pthread_attr_t attr;
struct sched_param sch_params;
pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr, &sch_params);
sch_params.sched_priority = 99;
//pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &sch_params);
pthread_create(&thread1, &attr, thread1Func, NULL);
sch_params.sched_priority = 1;
pthread_create(&thread2, &attr, thread2Func, NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
printf("Final Counter: %d\n", counter->value);
return 0;
}
When I use mutex_lock inside loop, my code spends huge time in execution, and I can't get the output.
I know lock () take time, but not as this!
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int x = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *fnC()
{
int i;
for (i = 0; i < 2; i++)
{
pthread_mutex_lock(&mutex);
x++;
}
printf(" %d", x);
pthread_mutex_unlock(&mutex);
}
int main()
{
int rt1, rt2;
pthread_t t1, t2;
/* Create two threads */
if ((rt1 = pthread_create(&t1, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt1);
if ((rt2 = pthread_create(&t2, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt2);
/* Wait for both threads to finish */
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("\n");
return 0;
}
Anyone can explain this?
I an learning pthread and I have a few questions.
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define NUM_THREADS 10
using namespace std;
void *PrintHello(void *threadid)
{
int* tid;
tid = (int*)threadid;
for(int i = 0; i < 5; i++){
printf("Hello, World (thread %d)\n", *tid);
}
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
int t;
int* valPt[NUM_THREADS];
for(t=0; t < NUM_THREADS; t++){
printf("In main: creating thread %d\n", t);
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
The code runs well and I don't call pthread_join. So I want to know, is pthread_join a must?
Another issue, is:
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
equal to:
rc = pthread_create(&threads[t], NULL, PrintHello, &i);
It is not. But you need either pthread_exit() or pthread_join().
Here you called pthread_exit(), thats why the child threads continue execution even after the main thread terminates.
If there is any need for the main thread to wait till the child threads complete execution, you can use pthread_join().
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;
}
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);
}