argument passed to function in pthread_create - c

I'm experimenting with pthreads and for the following code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* print_thread_num(void *index);
int main(int argc, char** argv) {
int i;
pthread_t threads[3];
for (i = 0; i < 3; i++) {
void *index = &i;
printf("Creating thread %d\n", i);
pthread_create(&threads[i], NULL, print_thread_num, index);
}
pthread_exit(NULL);
}
void* print_thread_num(void *index) {
int i = *(int*)index;
printf("I am the thread at index %d\n", i);
pthread_exit(NULL);
}
I'm getting the output below:
Creating thread 0
Creating thread 1
I am the thread at index 1
Creating thread 2
I am the thread at index 2
I am the thread at index 3
Why is each "I am the thread at index" printing an index higher than what it should print?

You're passing the address of your loop variable i, this is being incremented in the main thread while your child threads access it.

Related

Synchronize threads from different processes using semaphore

I have problem with semaphore in C. I have a parent process and a child process. Both can create 3 threads and I must display the beginning and the end of threads and I must impose the next condition: the thread with id 1 from parent process must display its beginning after the thread with id 2 from child process display its end. I use a semaphore, but when I do wait, the thread with id 1 from parent process it doesn't remain stuck at semaphore and continue to display the beginning. I can't use function usleep() or sleep().
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
sem_t* s=NULL;
void* function1(void* arg)
{
int* nrth=(int*) arg;
sem_t * s=NULL;
s=sem_open("mysemaphore",O_EXCL);
if(s==NULL)
perror("Error");
if(*nrth==1)
sem_wait(s);
printf("Begin P1, thread %d\n",*nrth);
printf("End P1, thread %d\n",*nrth);
sem_close(s);
return 0;
}
void* function2(void* arg)
{
int* nrth=(int*) arg;
sem_t * s=NULL;
s=sem_open("mysemaphore",O_EXCL);
if(s==NULL)
perror("Error");
printf("Begin P2, thread %d\n",*nrth);
printf("End P2, thread %d\n",*nrth);
if(*nrth==2)
sem_post(s);
sem_close(s);
return 0;
}
int main()
{
sem_unlink("mysemaphore");
s=sem_open("mysemaphore",O_CREAT,0644,1);
if(s==NULL)
perror("ERROR!");
pthread_t threads[4];
int index[4];
pthread_t threads2[4];
int index2[4];
if(fork()==0)
{
printf("Begin: process 2 \n");
for(int i=1; i<=3; i++)
{
index2[i]=i;
pthread_create(&threads2[i],NULL,function2,&index2[i]);
}
for(int i=1; i<=3; i++)
{
pthread_join(threads2[i],NULL);
}
printf("End: process 2 \n");
}
else
{
printf("Begin: process 1\n");
for(int i=1; i<=3; i++)
{
index[i]=i;
pthread_create(&threads[i],NULL,function1,&index[i]);
}
for(int i=1; i<=3; i++)
{
pthread_join(threads[i],NULL);
}
printf("End: process 2 \n");
wait(NULL);
}
return 0;
}
You are destroying your semaphore in both function1() and function2() when you call sem_destroy(), after which the behavior of that semaphore is undefined. That may be your biggest problem.
You should be using sem_close() instead after you are finished using the semaphore that you obtained from sem_open().

using threads for the first time

//trying to make each thread print its thread number not id and then print a message from the array would like to be able to pass array in pthread create but right now I am getting a an error array subscript is not an integer please help me
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
void * print_funtion( void* i, void* message)
{
printf("Thread %d: ",(int*) i);
printf("Thread %s: ", message);
return NULL;
}
int main(int argc, char* argv[]){
int i;
int num = atoi(argv[1]);
//printf("%d \n", num);
for(i = 1; i <= num; i++)
{
char *messages[] = {"Hello", "Bonjour", "Hola", "Shalom", "Namaste", "Gutan Tag", "God dag","Ola", "Salut", "Napot", "Dia"};
//printf("%d \n", i);
pthread_t tid;
pthread_create(&tid, NULL, print_funtion,(void*)i, (void*)messages[i]);
pthread_join(tid,NULL);
}
return 0;
}
There are many problems in the code and I'll point them out individually as comments:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
// Note: In most cases, you should use (char *) for strings instead of char[XX].
// Note: You don't need to set the number of elements in the array
// because it is automatically inferred from the initializer.
char *messages[] = {"Hello", "Bonjour", "Hola", "Shalom", "Namaste", "Gutan Tag", "God dag","Ola", "Salut", "Napot", "Dia"};
void *print_function(void *data)
{
// The data you passed is int not a pointer to int.
int i = (int)data;
printf("Thread %d: \n", i);
// You need to use %s for printing string.
printf("Message: %s\n", messages[i]);
return NULL;
}
int main(int argc, char* argv[])
{
int i;
int num = atoi(argv[1]);
// Limit the number of running threads so you don't slow down you computer (10 is already too much. It depends on the number of cores you CPU has).
#define MAX_NUM_OF_THREADS 10
if(num > MAX_NUM_OF_THREADS)
num = MAX_NUM_OF_THREADS;
// I explain why we need to store the thread ids down below.
pthread_t thread_ids[MAX_NUM_OF_THREADS];
for(i = 0; i < num; i++)
{
pthread_t tid;
void *thread_data = (void *)(i + 1);
pthread_create(&tid, NULL, print_function, thread_data);
thread_ids[i] = tid;
}
// You can't join with the thread in the previous loop because it will serialize thread creation.
// Meaning the program will not create the next thread before the current thread finish execution.
// Instead, you need to create all the threads first then you join to them one by one afterward.
// And for that you need to store the thread ids for each thread in order to join with them after they are created.
for(i = 0; i < num; i++)
{
pthread_join(thread_ids[i], NULL);
}
return 0;
}

Pthread id and sleep

I need to do the following:
Create a thread that creates 10 threads in a row.
Each thread just prints it's ID and sleeps for n seconds, where n is the serial number of current thread.
But, I can't get passing arguments right, when I run my code it seems like the thread is just sleeping.. Some help, please?
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
# define N 10
void* printID (void *i)
{
int* p=(int*) i;
sleep(p);
pthread_exit(NULL);
}
void* th (void* unused)
{
int sec,i;
sec=1;
i=1;
while(i<=10){
pthread_t pid1;
pthread_create (&pid1, NULL, &printID, (void *)&i);
pthread_join(pid1,NULL);
printf("Thread ID je: %d \n",(int) pid1);
i=i+1;
}
}
int main(){
pthread_t pid;
pthread_create (&pid, NULL, &th, NULL);
pthread_join(pid,NULL);
return 0;
}
Your argument passing is fine. But you are not passing the value to sleep.
It should be
sleep(*p);
p points the address of i (from the function th()). You need to dereference the pointer to get the value.

Achive interleaving multi-thread execution

I have two methods, fun1 and fun2, which are called by two different set of threads. I want to interleave their execution in a random order, the same way the order is random inside each of the two set of threads. How can I achieve this?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
void * function1(){
printf("function 1\n");
pthread_exit(NULL);
}
void * function2(){
printf("function 2\n");
pthread_exit(NULL);
}
int main(int argc, char ** argv){
int i;
int error;
int status;
int number_threads1 = 4;
int number_threads2 = 3;
pthread_t thread1[number_threads1];
pthread_t thread2[number_threads2];
for (i = 0; i < number_threads1; i++){
error = pthread_create(&thread1[i], NULL, function1, NULL);
if(error){return (-1);}
}
for(i = 0; i < number_threads1; i++) {
error = pthread_join(thread1[i], (void **)&status);
if(error){return (-1);}
}
for (i = 0; i < number_threads2; i++){
error = pthread_create(&thread2[i], NULL, function2, NULL);
if(error){return (-1);}
}
for(i = 0; i < number_threads2; i++) {
error = pthread_join(thread2[i], (void **)&status);
if(error){return (-1);}
}
}
Output:
function 1
function 1
function 1
function 1
function 2
function 2
function 2
Desired output:
Random order of both function 1 and function 2
By this I want to interleave their execution in a random order if you mean fun1 and fun2 to be executed in no fixed order then remove the loop with pthread_join() calls after the creating first group of threads (which waits for the first group to finish execution) and put it after creating all threads.
By the way if you simply want the threads to finish the execution on their own and there's no need for main thread to check status , then there's no need for pthread_join() calls at all. You can altogethter remove the two loops involving pthread_join calls and simply call pthread_exit(NULL); instead, after creating all the threads which will allow all threads to continue while only main thread will exit.

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