Why are my threads I created not printed in order?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have this program:
void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;
printf("My ID is %dn" , *id);
pthread_mutex_unlock(&mutex);
}
int main() {
int i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
return 0;
}
I expected it to output this:
My ID is 0
My ID is 1
My ID is 2
But instead I get random output, such as this:
My ID is 0
My ID is 0
My ID is 2
Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?
c multithreading pthreads race-condition
add a comment |
I have this program:
void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;
printf("My ID is %dn" , *id);
pthread_mutex_unlock(&mutex);
}
int main() {
int i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
return 0;
}
I expected it to output this:
My ID is 0
My ID is 1
My ID is 2
But instead I get random output, such as this:
My ID is 0
My ID is 0
My ID is 2
Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?
c multithreading pthreads race-condition
add a comment |
I have this program:
void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;
printf("My ID is %dn" , *id);
pthread_mutex_unlock(&mutex);
}
int main() {
int i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
return 0;
}
I expected it to output this:
My ID is 0
My ID is 1
My ID is 2
But instead I get random output, such as this:
My ID is 0
My ID is 0
My ID is 2
Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?
c multithreading pthreads race-condition
I have this program:
void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;
printf("My ID is %dn" , *id);
pthread_mutex_unlock(&mutex);
}
int main() {
int i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
return 0;
}
I expected it to output this:
My ID is 0
My ID is 1
My ID is 2
But instead I get random output, such as this:
My ID is 0
My ID is 0
My ID is 2
Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?
c multithreading pthreads race-condition
c multithreading pthreads race-condition
edited Nov 26 '18 at 23:51
ruakh
128k14206260
128k14206260
asked Nov 26 '18 at 23:43
CSDUGCSDUG
596
596
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Here id
points to the same variable i
in main for all the threads.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
But the variable i
is constantly being update by the two for
-loops in main
behind the threads back. So before the thread reaches the point of printf
, the value of i
, and therefore also the value of *id
, may have changed.
There are a few ways to solve this. The best way depends on the use case:
- Wait in
main
until the thread signals that it has made a copy of*id
before modifyingi
or letting it go out of scope. - Declare and initialize an array,
int thread_id
, and create the threads like this:
pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
some memory and and initialize it with a copy ofi
:
int *thread_id = malloc(sizeof(*thread_id));
*thread_id = i
pthread_create(&tid[i], NULL, func, thread_id);
Just don't forget to
free
your memory int the thread when you are finished using it. Or inmain
if the thread fails to start.
If
i
fits in avoid *
can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it asintptr_t
rather thanint
(We basicly abuse the fact that pointers are nothing more than magic integers) :
void *func(void *arg) {
pthread_mutex_lock(&mutex);
// Here we interpret a pointer value as an integer value
intptr_t id = (intptr_t )arg;
printf("My ID is %dn" , (int)id);
pthread_mutex_unlock(&mutex);
}
int main() {
intptr_t i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
// Here we squeeze the integer value of `i` into something that is
// supposed to hold a pointer
pthread_create(&tid[i], NULL, func, (void *)i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
// This does not belong here !!
// pthread_exit(NULL);
return 0;
}
add a comment |
Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.
I'm assuming you declared the variable mutex
globally and called pthread_mutex_init()
somewhere to initialize it.
Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
1
There is, in fact, a race condition:main()
's local variablei
is incremented (by the for-loops inmain()
) without first locking the mutex. The threads read the current value ofi
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.
– Jeremy Friesner
Nov 27 '18 at 1:21
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%2f53490737%2fwhy-are-my-threads-i-created-not-printed-in-order%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here id
points to the same variable i
in main for all the threads.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
But the variable i
is constantly being update by the two for
-loops in main
behind the threads back. So before the thread reaches the point of printf
, the value of i
, and therefore also the value of *id
, may have changed.
There are a few ways to solve this. The best way depends on the use case:
- Wait in
main
until the thread signals that it has made a copy of*id
before modifyingi
or letting it go out of scope. - Declare and initialize an array,
int thread_id
, and create the threads like this:
pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
some memory and and initialize it with a copy ofi
:
int *thread_id = malloc(sizeof(*thread_id));
*thread_id = i
pthread_create(&tid[i], NULL, func, thread_id);
Just don't forget to
free
your memory int the thread when you are finished using it. Or inmain
if the thread fails to start.
If
i
fits in avoid *
can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it asintptr_t
rather thanint
(We basicly abuse the fact that pointers are nothing more than magic integers) :
void *func(void *arg) {
pthread_mutex_lock(&mutex);
// Here we interpret a pointer value as an integer value
intptr_t id = (intptr_t )arg;
printf("My ID is %dn" , (int)id);
pthread_mutex_unlock(&mutex);
}
int main() {
intptr_t i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
// Here we squeeze the integer value of `i` into something that is
// supposed to hold a pointer
pthread_create(&tid[i], NULL, func, (void *)i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
// This does not belong here !!
// pthread_exit(NULL);
return 0;
}
add a comment |
Here id
points to the same variable i
in main for all the threads.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
But the variable i
is constantly being update by the two for
-loops in main
behind the threads back. So before the thread reaches the point of printf
, the value of i
, and therefore also the value of *id
, may have changed.
There are a few ways to solve this. The best way depends on the use case:
- Wait in
main
until the thread signals that it has made a copy of*id
before modifyingi
or letting it go out of scope. - Declare and initialize an array,
int thread_id
, and create the threads like this:
pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
some memory and and initialize it with a copy ofi
:
int *thread_id = malloc(sizeof(*thread_id));
*thread_id = i
pthread_create(&tid[i], NULL, func, thread_id);
Just don't forget to
free
your memory int the thread when you are finished using it. Or inmain
if the thread fails to start.
If
i
fits in avoid *
can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it asintptr_t
rather thanint
(We basicly abuse the fact that pointers are nothing more than magic integers) :
void *func(void *arg) {
pthread_mutex_lock(&mutex);
// Here we interpret a pointer value as an integer value
intptr_t id = (intptr_t )arg;
printf("My ID is %dn" , (int)id);
pthread_mutex_unlock(&mutex);
}
int main() {
intptr_t i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
// Here we squeeze the integer value of `i` into something that is
// supposed to hold a pointer
pthread_create(&tid[i], NULL, func, (void *)i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
// This does not belong here !!
// pthread_exit(NULL);
return 0;
}
add a comment |
Here id
points to the same variable i
in main for all the threads.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
But the variable i
is constantly being update by the two for
-loops in main
behind the threads back. So before the thread reaches the point of printf
, the value of i
, and therefore also the value of *id
, may have changed.
There are a few ways to solve this. The best way depends on the use case:
- Wait in
main
until the thread signals that it has made a copy of*id
before modifyingi
or letting it go out of scope. - Declare and initialize an array,
int thread_id
, and create the threads like this:
pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
some memory and and initialize it with a copy ofi
:
int *thread_id = malloc(sizeof(*thread_id));
*thread_id = i
pthread_create(&tid[i], NULL, func, thread_id);
Just don't forget to
free
your memory int the thread when you are finished using it. Or inmain
if the thread fails to start.
If
i
fits in avoid *
can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it asintptr_t
rather thanint
(We basicly abuse the fact that pointers are nothing more than magic integers) :
void *func(void *arg) {
pthread_mutex_lock(&mutex);
// Here we interpret a pointer value as an integer value
intptr_t id = (intptr_t )arg;
printf("My ID is %dn" , (int)id);
pthread_mutex_unlock(&mutex);
}
int main() {
intptr_t i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
// Here we squeeze the integer value of `i` into something that is
// supposed to hold a pointer
pthread_create(&tid[i], NULL, func, (void *)i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
// This does not belong here !!
// pthread_exit(NULL);
return 0;
}
Here id
points to the same variable i
in main for all the threads.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
But the variable i
is constantly being update by the two for
-loops in main
behind the threads back. So before the thread reaches the point of printf
, the value of i
, and therefore also the value of *id
, may have changed.
There are a few ways to solve this. The best way depends on the use case:
- Wait in
main
until the thread signals that it has made a copy of*id
before modifyingi
or letting it go out of scope. - Declare and initialize an array,
int thread_id
, and create the threads like this:
pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
some memory and and initialize it with a copy ofi
:
int *thread_id = malloc(sizeof(*thread_id));
*thread_id = i
pthread_create(&tid[i], NULL, func, thread_id);
Just don't forget to
free
your memory int the thread when you are finished using it. Or inmain
if the thread fails to start.
If
i
fits in avoid *
can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it asintptr_t
rather thanint
(We basicly abuse the fact that pointers are nothing more than magic integers) :
void *func(void *arg) {
pthread_mutex_lock(&mutex);
// Here we interpret a pointer value as an integer value
intptr_t id = (intptr_t )arg;
printf("My ID is %dn" , (int)id);
pthread_mutex_unlock(&mutex);
}
int main() {
intptr_t i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
// Here we squeeze the integer value of `i` into something that is
// supposed to hold a pointer
pthread_create(&tid[i], NULL, func, (void *)i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
// This does not belong here !!
// pthread_exit(NULL);
return 0;
}
answered Nov 27 '18 at 1:16
HAL9000HAL9000
27217
27217
add a comment |
add a comment |
Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.
I'm assuming you declared the variable mutex
globally and called pthread_mutex_init()
somewhere to initialize it.
Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
1
There is, in fact, a race condition:main()
's local variablei
is incremented (by the for-loops inmain()
) without first locking the mutex. The threads read the current value ofi
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.
– Jeremy Friesner
Nov 27 '18 at 1:21
add a comment |
Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.
I'm assuming you declared the variable mutex
globally and called pthread_mutex_init()
somewhere to initialize it.
Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
1
There is, in fact, a race condition:main()
's local variablei
is incremented (by the for-loops inmain()
) without first locking the mutex. The threads read the current value ofi
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.
– Jeremy Friesner
Nov 27 '18 at 1:21
add a comment |
Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.
I'm assuming you declared the variable mutex
globally and called pthread_mutex_init()
somewhere to initialize it.
Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.
I'm assuming you declared the variable mutex
globally and called pthread_mutex_init()
somewhere to initialize it.
Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.
int *id = (int *)arg;
printf("My ID is %dn" , *id);
edited Nov 27 '18 at 13:08
answered Nov 27 '18 at 0:05
GandhiGandhiGandhiGandhi
1045
1045
1
There is, in fact, a race condition:main()
's local variablei
is incremented (by the for-loops inmain()
) without first locking the mutex. The threads read the current value ofi
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.
– Jeremy Friesner
Nov 27 '18 at 1:21
add a comment |
1
There is, in fact, a race condition:main()
's local variablei
is incremented (by the for-loops inmain()
) without first locking the mutex. The threads read the current value ofi
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.
– Jeremy Friesner
Nov 27 '18 at 1:21
1
1
There is, in fact, a race condition:
main()
's local variable i
is incremented (by the for-loops in main()
) without first locking the mutex. The threads read the current value of i
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.– Jeremy Friesner
Nov 27 '18 at 1:21
There is, in fact, a race condition:
main()
's local variable i
is incremented (by the for-loops in main()
) without first locking the mutex. The threads read the current value of i
while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.– Jeremy Friesner
Nov 27 '18 at 1:21
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%2f53490737%2fwhy-are-my-threads-i-created-not-printed-in-order%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