I have the following functions :
void *foo(void *i) {
int a = (int) i;
}
int main() {
pthread_t thread;
int i;
pthread_create(&thread, 0, foo, (void *) i);
}
At compilation, there are some errors about casting ((void *) i and int a = (int) i). How can I pass an integer as the last argument of pthread_create properly?
Building on szx's answer (so give him the credit), here's how it would work in your for loop:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
for ( int i = 0; i < 10; ++1 ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(EXIT_FAILURE);
}
*arg = i;
pthread_create(&thread, 0, foo, arg);
}
/* Wait for threads, etc */
return 0;
}
On each iteration of the loop, you're allocating new memory, each with a different address, so the thing that gets passed to pthread_create() on each iteration is different, so none of your threads ends up trying to access the same memory and you don't get any thread safety issues in the way that you would if you just passed the address of i. In this case, you could also set up an array and pass the addresses of the elements.
You can allocate an int on the heap and pass it to pthread_create(). You can then deallocate it in your thread function:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
int *i = malloc(sizeof(*i));
pthread_create(&thread, 0, foo, (void *) i);
}
You should cast the address of i (rather than the value of i as you do now) in the last argument of pthread_create().
pthread_create(&thread, 0, foo, (void *) &i);
^ is missing
And the casting is wrong in your function too. It should be:
int a = *((int*) i);
If you intend to read the value, you should also initialize i to some value in main() as it's uninitialized now.
2 Use proper definition for main():
int main(void)
or int main(int argc, char *argv[]) or its equivalent.
Old question, but I faced the same problem today, and I decided not to follow this path.
My application was really about performance, so I chose to have this array of ints declared statically.
Since I don't know a lot of applications where your pthread_join / pthread_cancel is in another scope than your pthread_create, I chose this way :
#define NB_THREADS 4
void *job(void *_i) {
unsigned int i = *((unsigned int *) _i);
}
int main () {
unsigned int ints[NB_THREADS];
pthread_t threads[NB_THREADS];
for (unsigned int i = 0; i < NB_THREADS; ++i) {
ints[i] = i;
pthread_create(&threads[i], NULL, job, &ints[i]);
}
}
I find it more elegant, more efficient, and you don't have to worry about freeing since it only lives in this scope.
While this is an old question there is one option missing when all you need is to pass a positive integer like a descriptor: you can pass it directly as the address, while it it a hack it works well and avoid allocating anything :)
NOTE: the size of the integer must match the size of a pointer on your OS but nowadays most systems are native 64bits.
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
void *_thread_loop(void *p)
{
uint64_t n = (uint64_t)p;
printf("received %llu\n", n);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t read_thread_id;
uint64_t n = 42;
pthread_create(&read_thread_id, NULL, _thread_loop, (void *)n);
pthread_join(read_thread_id, NULL);
return 0;
}
Related
I have found several codes using dynamic memory allocation method for passing an integer as the last argument, like this example:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
for ( int i = 0; i < 10; ++1 ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(EXIT_FAILURE);
}
*arg = i;
pthread_create(&thread, 0, foo, arg);
}
/* Wait for threads, etc */
return 0;
}
Otherwise, I found academic examples that use an array method, like this example passing a struct:
//Runnable example
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct my_Struct{
int index;
int value;
};
void* my_Func(void *received_struct){
struct my_Struct *struct_ptr = (struct my_Struct*) received_struct;
printf("index: %d | value: %d \n", struct_ptr->index, struct_ptr->value);
//Now use 'struct_ptr->index', 'struct_ptr->value' as you wish
}
int main(){
struct my_Struct mystruct_1[5];
printf("\nEnter 5 numbers:\n");
for (int i=0; i<5; i++){
scanf("%d", &mystruct_1[i].value);
mystruct_1[i].index = i;
}
pthread_t tid[5];
for(int i=0; i<5; i++){
pthread_create(&(tid[i]), NULL, my_Func, &mystruct_1[i]);
}
for (int i=0; i<5; i++){
pthread_join(tid[i], NULL);
}
}
//To run: gcc [C FILE].c -lpthread -lrt
// ./a.out
//Grepper Profile: https://www.codegrepper.com/app/profile.php?id=9192
What is the advantage of the dynamic memory allocation method?
Update: I found in the IBM i documentation, based on gcc, that they use memory allocation
The last parameter of pthread_create() is passed on the stack of the newly created thread. When it is an integer or anything else which the size is little or equal than the size of a pointer, the parameter can be passed as it is to pthread_create() with a cast. But it is not the recommended way to make it as it is not portable on machines where for example the integers do not have the same size as the pointers. Let's compile the following simple program:
#include <pthread.h>
#include <stdio.h>
void* thread_task(void* arg)
{
printf("Thread received parameter: %d\n", (int)arg);
return NULL;
}
int main(void)
{
pthread_t tid;
int i = 45;
pthread_create(&tid, NULL, thread_task, (void *)i);
pthread_join(tid, NULL);
return 0;
}
The gcc compiler raises the following warnings:
$ gcc pcreate.c -o pcreate -lpthread
pcreate.c: In function ‘thread_task’:
pcreate.c:6:45: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
printf("Thread received parameter: %d\n", (int)arg);
^
pcreate.c: In function ‘main’:
pcreate.c:15:43: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&tid, NULL, thread_task, (void *)i);
Hence, using a pointer on a structure or a table entry or a dynamically allocated memory area is the way to make it portable. The preceding program could be fixed as:
#include <pthread.h>
#include <stdio.h>
void* thread_task(void* arg)
{
printf("Thread received parameter: %d\n", *((int *)arg));
return NULL;
}
int main(void)
{
pthread_t tid;
int t[1] = { 45 };
pthread_create(&tid, NULL, thread_task, (void *)t);
pthread_join(tid, NULL);
return 0;
}
The compiler no longer raises any warnings:
$ gcc pcreate.c -o pcreate -lpthread
$ ./pcreate
Thread received parameter: 45
When you only want to pass one integer you can just cast it to a pointer:
void *foo(void *i) {
int a = (int)i;
}
for ( int i = 0; i < 10; ++1 ) {
pthread_create(&thread, 0, foo, (void*)i);
}
This gives maximum efficiency and no lifetime concerns.
I'm having a trouble passing a struct pointer into a function because I'm a bit confused with those pointers and references. I want to modify the thread.thread_num value from the thread_startfunction.
#include <stdio.h>
#include <stdlib.h> //malloc, free
#include <pthread.h>
#define N 5
// void *malloc(size_t);
struct thread {
pthread_t thread_id;
int thread_num;
// int thread_sum;
};
void *thread_start(void *thread)
{
struct thread *my_data;
my_data = (struct thread *)thread;
printf("num T: %i\n", my_data->thread_num);
my_data->thread_num=4;
printf("num T: %i\n", my_data->thread_num);
return NULL;
}
int main(int argc, char *argv[])
{
int i;
struct thread pthread_data;
struct thread *thread = &pthread_data;
thread->thread_num=2;
pthread_create(&thread->thread_id, NULL, thread_start, (void *)&thread);
printf("num: %i\n",thread->thread_num);
pthread_exit(NULL);
return 0;
}
But the value that print the main doesn't change (2).
And then I want to create an array of thread struct, but I don't know how exactly do that:
I guess it should be something like this:
int main(int argc, char *argv[])
{
int i;
struct thread pthread_data;
struct thread *thread[N-1] = &pthread_data; // I don't know how to manage this.
for(i=0; i<N; i++)
{
thread->thread_num=i;
pthread_create(&thread[i]->thread_id, NULL, thread_start, (void *)&thread[i]);
printf("num %i: %i\n",i,thread[i]->thread_num);
}
pthread_exit(NULL);
return 0;
}
Any thoughts?
I recommend you to read http://www.advancedlinuxprogramming.com/alp-folder/alp-ch04-threads.pdf
And here what you wanted:
#define N 5
typedef struct thread {
pthread_t thread_id;
int thread_num;
// int thread_sum;
} ThreadData;
void *thread_start(void *thread)
{
ThreadData *my_data = (ThreadData*)thread;
//there is no guarantee that prints will be in order
// we will use its initial thread->num ,cause it differs for each thread
//plus you will see how threads will behave
int order=my_data->thread_num;
printf("%i) before num T: %i\n",order, my_data->thread_num);
my_data->thread_num=4;
printf("%i) after assignment num T: %i\n",order ,my_data->thread_num);
return NULL;
}
int main(int argc, char *argv[])
{
int i;
ThreadData thread[N];
for(i=0; i<N; i++)
{
thread[i].thread_num=i;
pthread_create(&(thread[i].thread_id), NULL, thread_start, (void *)(thread+i));
}
//wait for all threads
for (i = 0; i < N; i++)
pthread_join(thread[i].thread_id, NULL);
//print results of each thread
for (i = 0; i < N; i++)
printf(" %i)thread: number %i\n",i,thread[i].thread_num);
return 0;
}
I can see multiple mistakes in your code.
First you have your pointers wrong. In the first example, it is enough to pass &pthread_data to pthread_create, &thread is the address of the thread pointer, so you are passing struct thread ** to your function instead of struct thread *. In the second example you should use (void *) thread[i]. &thread[i] is again struct thread **.
When you want each thread to write to its own thread data, then you should make an array of thread data, so that each thread has its own piece, else you will run into race conditions.
As others have already pointed out, you should call pthread_join before calling printf to ensure that the main thread will wait for all worker threads.
Also note that if you are calling pthread_join from other function that the one that spawned those threads, you have to ensure that the array of tread data will not go out of scope (in this case it would be probably better to use malloc or a global array).
You can't. As soon as main exits, which it does when you call pthread_exit, pthread_data ceases to exist, since it's local to the main function. So it can't be modified.
I simply want to pass the value of an integer to a thread.
How can I do that?
I tried:
int i;
pthread_t thread_tid[10];
for(i=0; i<10; i++)
{
pthread_create(&thread_tid[i], NULL, collector, i);
}
The thread method looks like this:
void *collector( void *arg)
{
int a = (int) arg;
...
I get the following warning:
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
The compiler will complain if you don't cast i to a void pointer:
pthread_create(&thread_tid[i], NULL, collector, (void*)i);
That said, casting an integer to a pointer isn't strictly safe:
ISO/IEC 9899:201x
6.3.2.3 Pointers
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
so you're better off passing a separate pointer to each thread.
Here's a full working example, which passes each thread a pointer to a separate element in an array:
#include <pthread.h>
#include <stdio.h>
void * collector(void* arg)
{
int* a = (int*)arg;
printf("%d\n", *a);
return NULL;
}
int main()
{
int i, id[10];
pthread_t thread_tid[10];
for(i = 0; i < 10; i++) {
id[i] = i;
pthread_create(&thread_tid[i], NULL, collector, (void*)(id + i));
}
for(i = 0; i < 10; i++) {
pthread_join(thread_tid[i], NULL);
}
return 0;
}
There's a nice intro to pthreads here.
int is 32 bit, and void * is 64 bit in 64bit Linux; In that case you should use long int instead of int;
long int i;
pthread_create(&thread_id, NULL, fun, (void*)i);
int fun(void *i) function
long int id = (long int) i;
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main {
int *arg = (char*)malloc(sizeof(char))
pthread_create(&thread, 0, foo, arg);
}
It better to use of a struct for send more parameters in one :
struct PARAMS
{
int i;
char c[255];
float f;
} params;
pthread_create(&thread_id, NULL, fun, (void*)(¶ms));
then you can cast params to PARAMS* and use of it in pthread routine:
PARAMS *p = static_cast<PARAMS*>(params);
p->i = 5;
strcpy(p->c, "hello");
p->f = 45.2;
Is it possible to cast a pointer to an unsigned int, then later cast it back to a pointer? I'm trying to store the pointer to a struct in a pthread_t variable, but I can't seem to get it to work. Here's some snippets of my code (I'm creating a user-level thread management library). When I try to print out the tid of the thread it gives me some long garbage number.
Edit: Never mind, I got it to work.
I changed
thread = (pthread_t) currentThread;
to
*thread = (pthread_t) currentThread;
Figured it was something stupid like that.
Test program:
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, runner, NULL);
pthread_create(&thread2, NULL, runner, NULL);
pthread_join(&thread2, NULL);
My library:
typedef struct queueItem
{
int tid;
ucontext_t context;
int caller;
struct queueItem *joiningOn;
struct queueItem *nextContext;
} queueItem;
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
{
thread = (pthread_t) currentThread;
}
...
int pthread_join(pthread_t thread, void **retval)
{
queueItem *t = (queueItem *) thread;
if(runningContext->joiningOn != NULL) // Current thread is already waiting on another
return EINVAL;
if(t == NULL) // If thread to join on is invalid
return 0;
fprintf(stdout, "JOINEE: %d\n", t->tid); // Prints weird number
runningContext->caller = JOIN;
runningContext->joiningOn = t;
swapcontext(&(runningContext->context), &scheduleContext);
}
No. On many systems pointer type is bigger than int type. If you have a problem to use pthread_t, ask about it, int is not the answer.
For example, on my machine, the following code:
#include <stdio.h>
int main() {
printf("unsigned int = %lu\n", sizeof(unsigned int));
printf("pointer = %lu\n", sizeof(void*));
return 0;
}
outputs:
unsigned int = 4
pointer = 8
Sure it's possible, if you make sure your unsigned int is the same size as a void* on your system.
If you have some code that's not working, post it.
Edit: You should read about intptr_t, e.g. here: Why / when to use `intptr_t` for type-casting in C?
I have to use the clone() system call in the main-function to get 2 threads. (I know, there are other options, but in this case, it has to be clone()).
The system call works and both threads arrive in the designated function (foo). But in this function I need them to call another function with this signature:
void increment(int* a, int b)
(Sidenote: It adds b * 1 to a. (= a+b))
The important thing is, that both, a and b, are declared in the main-function and I don't know how to pass them to foo.
I already tried different things, but without success. I've gotten a hint: Use an adapter.
But I have no clue how to do this. (I also dont know how to use the args in clone with int.)
Any suggestions?
One of the arguments to clone() is a void* arg. This lets you pass a void pointer to your function. In order to pass an int pointer and an int instead, you have to create a struct with an int pointer and int assigned to a and b respectively, then cast a pointer to that struct into a void pointer. Then inside the function you reverse the process.
My C is a little rusty and I haven't compiled this, so don't quote me on it, but it should look roughly like this:
struct clone_args {
int* a;
int b
};
int main(int argc, char* argv[])
{
struct clone_args args;
args.a = a;
args.b = b;
void* arg = (void*)&args;
clone(fn, ..., arg, ...);
}
int fn(void* arg)
{
struct clone_args *args = (struct clone_args*)arg;
int* a = args->a;
int b = args->b;
}
Note: take care that the struct you create is still in scope when fn is called, as it isn't copied. You might have to malloc it.
Here is the example code:
#define stacksize 1048576
typedef struct
{
int ii;
int jj;
} someinput1;
static int /* Start function for cloned child */
childFunc(someinput1 *struc)
{
printf("Child: PID=%ld PPID=%ld\n", (long) getpid(), (long) getppid());
printf("Hi!! I am child process created by Clone %ld \n",(long) getpid());
printf("Value of x %d %d\n",struc->ii,struc->jj);
}
int main()
{
someinput1 inputtest;
int i;
char *stack; /* Start of stack buffer */
char *stack1; /* End of stack buffer */
pid_t pid;
stack = malloc(stacksize);
stack1 = stack + stacksize;
for (i = 0;i<5;i++)
{
inputtest.ii = i+5;
inputtest.jj = inputtest.ii + 10;
pid = clone(childFunc, stack1, NULL, (void *) (&inputtest));
printf("clone returned -- %ld \n", (long) pid);
}
sleep(1);
exit(EXIT_SUCCESS);
}