How to pass an int as “void *” to thread start function?
I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] createdt", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exitedt", i);
}
return 0;
}
c casting int pthreads void
add a comment |
I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] createdt", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exitedt", i);
}
return 0;
}
c casting int pthreads void
add a comment |
I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] createdt", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exitedt", i);
}
return 0;
}
c casting int pthreads void
I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] createdt", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exitedt", i);
}
return 0;
}
c casting int pthreads void
c casting int pthreads void
edited Nov 23 '18 at 2:10
efuddy
asked Nov 23 '18 at 2:00
efuddyefuddy
495
495
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
In the run()
function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run()
, you don't need to cast the arg
. Replace (int)arg
with arg
.
EDIT:
The way you are passing the argument to fun()
while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.
This is wrong. OP is erroneously passing the address ofi
instead of the value and this produces a data race.
– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
add a comment |
You don't need the cast in the call to pthread_create()
— the conversion to void *
is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main()
:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t
ensures the integer value is big enough to hold a pointer; the cast to void *
is needed because there isn't an implicit cast from any integer type to void *
. This ensures each thread function invocation has a different value. Sharing a pointer to an int
means that everything is uncontrolled.
add a comment |
@efuddy. Instead of (int)arg
you should use (int *)arg
to properly cast the **void pointer* void *arg
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439834%2fhow-to-pass-an-int-as-void-to-thread-start-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
In the run()
function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run()
, you don't need to cast the arg
. Replace (int)arg
with arg
.
EDIT:
The way you are passing the argument to fun()
while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.
This is wrong. OP is erroneously passing the address ofi
instead of the value and this produces a data race.
– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
add a comment |
In the run()
function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run()
, you don't need to cast the arg
. Replace (int)arg
with arg
.
EDIT:
The way you are passing the argument to fun()
while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.
This is wrong. OP is erroneously passing the address ofi
instead of the value and this produces a data race.
– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
add a comment |
In the run()
function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run()
, you don't need to cast the arg
. Replace (int)arg
with arg
.
EDIT:
The way you are passing the argument to fun()
while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.
In the run()
function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run()
, you don't need to cast the arg
. Replace (int)arg
with arg
.
EDIT:
The way you are passing the argument to fun()
while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.
edited Nov 23 '18 at 5:42
answered Nov 23 '18 at 2:16
H.S.H.S.
5,5741420
5,5741420
This is wrong. OP is erroneously passing the address ofi
instead of the value and this produces a data race.
– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
add a comment |
This is wrong. OP is erroneously passing the address ofi
instead of the value and this produces a data race.
– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
This is wrong. OP is erroneously passing the address of
i
instead of the value and this produces a data race.– R..
Nov 23 '18 at 3:55
This is wrong. OP is erroneously passing the address of
i
instead of the value and this produces a data race.– R..
Nov 23 '18 at 3:55
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
@R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.
– H.S.
Nov 23 '18 at 5:44
add a comment |
You don't need the cast in the call to pthread_create()
— the conversion to void *
is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main()
:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t
ensures the integer value is big enough to hold a pointer; the cast to void *
is needed because there isn't an implicit cast from any integer type to void *
. This ensures each thread function invocation has a different value. Sharing a pointer to an int
means that everything is uncontrolled.
add a comment |
You don't need the cast in the call to pthread_create()
— the conversion to void *
is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main()
:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t
ensures the integer value is big enough to hold a pointer; the cast to void *
is needed because there isn't an implicit cast from any integer type to void *
. This ensures each thread function invocation has a different value. Sharing a pointer to an int
means that everything is uncontrolled.
add a comment |
You don't need the cast in the call to pthread_create()
— the conversion to void *
is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main()
:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t
ensures the integer value is big enough to hold a pointer; the cast to void *
is needed because there isn't an implicit cast from any integer type to void *
. This ensures each thread function invocation has a different value. Sharing a pointer to an int
means that everything is uncontrolled.
You don't need the cast in the call to pthread_create()
— the conversion to void *
is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main()
:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t
ensures the integer value is big enough to hold a pointer; the cast to void *
is needed because there isn't an implicit cast from any integer type to void *
. This ensures each thread function invocation has a different value. Sharing a pointer to an int
means that everything is uncontrolled.
answered Nov 23 '18 at 2:26
Jonathan LefflerJonathan Leffler
571k926851034
571k926851034
add a comment |
add a comment |
@efuddy. Instead of (int)arg
you should use (int *)arg
to properly cast the **void pointer* void *arg
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
add a comment |
@efuddy. Instead of (int)arg
you should use (int *)arg
to properly cast the **void pointer* void *arg
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
add a comment |
@efuddy. Instead of (int)arg
you should use (int *)arg
to properly cast the **void pointer* void *arg
@efuddy. Instead of (int)arg
you should use (int *)arg
to properly cast the **void pointer* void *arg
answered Nov 23 '18 at 2:08
eapetchoeapetcho
42727
42727
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
add a comment |
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;
– efuddy
Nov 23 '18 at 2:15
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439834%2fhow-to-pass-an-int-as-void-to-thread-start-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown