number of arguments for a function in pthread - c

In hello world example of pthread it is stated:
#include <pthread.h>
#include <stdio.h>
void * print_hello(void *arg)
{
printf("Hello world!\n");
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thr;
if(pthread_create(&thr, NULL, &print_hello, NULL))
{
printf("Could not create thread\n");
return -1;
}
if(pthread_join(thr, NULL))
{
printf("Could not join thread\n");
return -1;
}
return 0;
}
As you can see print_hello in pthread_create() has no argument, however in the definition, it looks like void * print_hello(void *arg)
What does that mean?
Now assume I have this implementation
void * print_hello(int a, void *);
int main(int argc, char **argv)
{
pthread_t thr;
int a = 10;
if(pthread_create(&thr, NULL, &print_hello(a), NULL))
{
printf("Could not create thread\n");
return -1;
}
....
return 0;
}
void * print_hello(int a, void *arg)
{
printf("Hello world and %d!\n", a);
return NULL;
}
Now I get this error:
too few arguments to function print_hello
So how can I fix that?

pthread passes one argument of type void * to thread function, So you can pass a pointer to any type of data that you want as fourth argument of pthread_create function, look at the example below that fixes your code.
void * print_hello(void *);
int main(int argc, char **argv)
{
pthread_t thr;
int a = 10;
if(pthread_create(&thr, NULL, &print_hello, (void *)&a))
{
printf("Could not create thread\n");
return -1;
}
....
return 0;
}
void * print_hello(void *arg)
{
int a = (int)*arg;
printf("Hello world and %d!\n", a);
return NULL;
}

Related

simple pthread C program - Synchronization question

I got this simple C program that uses pthreads.
I basically want to call my_function() once I'm 100% sure that my_thread() gets called and is executed.
I need to know how to synchronize the main() function and the my_thread() function.
Please note that the my_thread() never returns.
#include <stdio.h>
#include <pthread.h>
void my_function (void);
void* my_thread (void* arg);
int main (int argc, char* argv[])
{
int rc;
pthread_t id;
rc = pthread_create(&id, NULL, my_thread, NULL);
if (rc != 0)
{
return -10;
}
/*
* I wanna call my_function() once I'm 100% sure my_thread() gets called and being executed
*/
/*
* Synchronization code to add here:
*/
my_function();
return 0;
}
void* my_thread (void* arg)
{
/*
* This pthread never returns
*/
while (1)
{
/* stuff */
};
}
void my_function (void)
{
printf("Hello\n");
}
Thanks for your help.
Can anybody check if this solution is correct?
It works using the debugger but I would like to have a comment from experienced programmers.
#include <stdio.h>
#include <pthread.h>
void my_function (void);
void* my_thread (void* arg);
int started;
pthread_mutex_t mutex;
pthread_t id;
int main (int argc, char* argv[])
{
int rc;
int done;
started = 0;
mutex = PTHREAD_MUTEX_INITIALIZER;
rc = pthread_create(&id, NULL, my_thread, NULL);
if (rc != 0)
{
return -10;
}
/*
* Synchronization code proposed:
*/
done = 0;
do
{
pthread_mutex_lock(&mutex);
if (started == 1)
{
done = 1;
}
pthread_mutex_unlock(&mutex);
}
while (done == 0);
/*
* I wanna call my_function() once I'm 100% sure
* that my_thread() is called and being executed
*/
my_function();
return 0;
}
void* my_thread (void* arg)
{
started = 1;
while (1)
{
/* stuff */
};
}
void my_function (void)
{
printf("Hello\n");
}

How to make two threads execute alternately?

I have two functions f1() and f2() I want f1() and f2() to execute
alternately, without using a loop: Not like this : loop {
f1();
f2(); }
I just want to use thread method My code is below:
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>
void *f1(void *vargp);
void *f2(void *vargp);
static sem_t mutex;
int main(int argc, char **argv) {
pthread_t tid1, tid2;
sem_init(&mutex, 0, 1);
pthread_create(&tid1, NULL, f1, NULL);
pthread_create(&tid2, NULL, f2, NULL);
sleep(100);
return 0;
}
void *f1(void *vargp) {
pthread_detach(pthread_self());
while (1) {
sem_wait(&mutex);
printf("In f1\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
void *f2(void *vargp) {
pthread_detach(pthread_self());
while(1) {
sem_wait(&mutex);
printf("In f2\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
The result always prints "In f1" What should I do ?

How to pass multiple values through command line arguments in void function?

#define SMALL_STACK 131072 //128K for stack
pthread_attr_t thread_attr; //for attr
void* fn(void* arg)
{ //fn fuction
printf("%d", (char *) arg);
return NULL;
}
int main(int argc, char** argv)
{
printf("Have ");
printf(" arguments:"); //checking multiple arguments
for (int i = 0; i < argc; ++i)
{
printf("%s", argv[i]);
}
printf("\n");
pthread_attr_init(&thread_attr);
pthread_attr_setstacksize(&thread_attr, SMALL_STACK);
pthread_t th; //creating thread and stack
/* I Need Help (void*)&argv[1] passing this to void *fn function printing the argument coming from command line arguments */
pthread_create(&th, &thread_attr, fn, (void*) &argv[1]); //creating thread
return 0;
}
In my opinion, you should pass a struct instance to your thread parameter.
Below, an example:
struct MyThreadData
{
int argc,
char** argv;
}
void* fn(void* arg)
{
MyThreadData* data=(MyThreadData*)arg;
/*code*/
return NULL;
}
int main(int argc, char** argv)
{
/*...*/
MyThreadData td={0};
td.argc=argc;
td.argv=argv;
void* ret = NULL;
pthread_create(&th, &thread_attr, fn, (void*)&td);
pthread_join(th,&ret)
}
To pass one argument (here: the 1st) change
pthread_create(&th, &thread_attr, fn, (void*)&argv[1]);
to be
pthread_create(&th, &thread_attr, fn, argv[1]);
To inside the thread function print the string use the correct conversion specifier:
printf("%s", (char *)arg);
or in a "cleaner" manner do
void* fn(void* arg)
{
char * pc = arg;
printf("%s\n", pc); /* add a new-line to flush stdout, to
have this printed immediately. */
To pass all arguments then change
pthread_create(&th, &thread_attr, fn, (void*)&argv[1]);
to be
pthread_create(&th, &thread_attr, fn, argv);
and adjust the thread function as follows:
void* fn(void* arg)
{
char ** ppc = arg;
while (*ppc)
{
printf("%s\n", *ppc);
++ppc;
}
...
Also make sure main() does not return the standard way, as this then ends the process, which in turn ends all threads of the process.
To do so replace
return 0;
by
pthread_exit(NULL);

Seg fault (core dumped) after pthread_join in C

I keep getting a seg fault (core dump) after pthread_join in my program. It prints out the expected result just fine, but seg faults when joining the thread. I have looked at several other discussions on this topic, but none of the suggested solutions seem to work in my case. Here is what my compile command looks like (no compile warnings or errors):
$ gcc -Wall -pthread test.c -o test
Here is the output:
$ ./test
1 2 3 4 5 6 7 8 9 10
Segmentation fault (core dumped)
And here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
void *fillArray(int *size) {
int i;
for (i = 0; i < *size; i++) {
array[i] = i+1;
}
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
rc = pthread_create(&thread, NULL, fillArray(&size), &res);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Any ideas what could be the cause?
This doesn't compile for me: It fails with
dummy.cpp: In function ‘int main(int, char**)’:
dummy.cpp:29: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
dummy.cpp:29: error: initializing argument 3 of ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
Which is because you're actually calling fillArray and passing its result to pthread_create, rather than passing the function pointer. I expect your code will need to look more like this (UNTESTED!) : (Note I changed signature of fillArray, created data struct type to pass to fillArray, changed how pthread_create is called)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
struct fillArrayData {
int * array;
int size;
int * result;
};
void *fillArray(void *void_data) {
fillArrayData * data = (fillArray*)void_data;
for (int i = 0; i < data.size; i++) {
data.array[i] = i+1;
}
//You could fill in some return info into data.result here if you wanted.
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
fillArrayData data;
data.array = array;
data.size = 10;
rc = pthread_create(&thread, NULL, fillArray, &data);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Error in
Calling function pointer
passing parameter to thread handler
In pthread prototype of pthread_create below
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
1st argument - pthread_variable
2nd argument - thread attrubutes
3rd argument - thread handler(function pointer name)
4th argument - variable need to pass thread handler.
In 4th argument - if two thread want to share single variable, then create global variable, and the pass this variable when creating thread.
sample program:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
further details here

passing pointer to function in pthread_create

I am trying to create a thread by passing a function pointer, however at this line
pthread_t start_thread(void *func, thread_data *tdata)
It gives me --
use-hello.c:23: error: invalid conversion from 'void*' to 'void* (*)(void*)
Any inputs please...
typedef struct thread_data{
int fd;
int threadId;
}thread_data;
pthread_t start_thread(void *func, thread_data *tdata)
{
pthread_t thread_id;
int rc;
printf("In main: creating thread\n");
rc = pthread_create(&thread_id, NULL, func, tdata);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
return(thread_id);
}
void thread_function1(thread_data *tdata){
.
.
}
int main(int argc, char **argv){
/* Our file descriptor */
int fd;
int rc = 0;
printf("%s: entered\n", argv[0]);
/* Open the device */
fd = open("/dev/hello1", O_RDWR);
if ( fd == -1 ) {
perror("open failed");
rc = fd;
exit(-1);
}
printf("%s: open: successful, fd=%d\n", argv[0], fd);
//array of function pointers
void (*function[5])(thread_data*);
function[0] = thread_function0;
function[1] = thread_function1;
function[2] = thread_function2;
function[3] = thread_function3;
function[4] = thread_function4;
//start threads
for(int i=0; i<2; i++){
thread_data *tdata[i] = (thread_data*)malloc(sizeof(thread_data));
tdata[i]->threadId = i;
tdata[i]->fd = fd;
printf("starting thread = %d\n",start_thread(function[i]), tdata[i]));
}
while(1) sleep(1); // infinite loop
printf("closing file descriptor..\n");
close(fd);
printf("file descriptor closed..\n");
return 0;
}
The problem is your declaration of start_thread, it takes a void* rather than a function pointer.
Change it to:
pthread_t start_thread(void *(*func) (thread_data *), thread_data *tdata);
A typedef for that function pointer type would simplify both that prototype and your array declaration.
typedef void (*thread_func)(thread_data*);
pthread_t start_thread(thread_func func, thread_data *tdata);
thread_func function[5];
Your function takes func as void*
pthread_t start_thread(void *func, thread_data *tdata)
And then you pass it to pthread_create as 3rd argument which should be void *(*) (void *)

Resources