* thread: reentrant question
@ 2009-12-24 18:41 Randi Botse
2009-12-24 19:30 ` vinit dhatrak
0 siblings, 1 reply; 6+ messages in thread
From: Randi Botse @ 2009-12-24 18:41 UTC (permalink / raw)
To: linux-c-programming
Hi all,
I'm now learning thread reentrancy on Linux, so i write simple codes
for demonstration:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void *data)
{
char *ptr;
ptr = malloc(8);
printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
free(ptr);
return NULL;
}
#define NTHREAD 5
int main(void)
{
pthread_t thread[NTHREAD];
int i;
for (i = 0; i < NTHREAD; i++)
if (pthread_create(&thread[i], NULL, func, (void*) &i))
return -1;
for (i = 0; i < NTHREAD; i++)
pthread_join(thread[i], NULL);
return 0;
}
I know the func() function is not reentrant, worst printf() debugging
told me that's each thread pointer to character (ptr) may has same
address, like this output:
thread1 -> ptr at: 0x9a80128
thread1 -> ptr at: 0x9a80138
thread2 -> ptr at: 0x9a801d8
thread4 -> ptr at: 0x9a801d8
thread4 -> ptr at: 0x9a801d8
I try to modify the func() by not free ptr to be:
void *func(void *data)
{
char *ptr;
ptr = malloc(8);
printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
/* free(ptr); */
return NULL;
}
And the result is i always got different address of each thread's ptr, such as:
thread0 -> ptr at: 0x8db2098
thread1 -> ptr at: 0x8db2138
thread2 -> ptr at: 0x8db21d8
thread3 -> ptr at: 0x8db2278
thread4 -> ptr at: 0x8db2318
Can you explain me why this happen? how about my printf() debugging
method? it's works for this demonstration?
Thanks before.
- Randi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: thread: reentrant question
2009-12-24 18:41 thread: reentrant question Randi Botse
@ 2009-12-24 19:30 ` vinit dhatrak
2009-12-26 5:32 ` Randi Botse
0 siblings, 1 reply; 6+ messages in thread
From: vinit dhatrak @ 2009-12-24 19:30 UTC (permalink / raw)
To: Randi Botse; +Cc: linux-c-programming
Hi Randi,
You are observing this because of malloc's behaviour. If you allocate
and free same-sized memory multiple times, then malloc tries to reuse
the memory. You can try this by putting malloc/free statements in a
loop.
In your case, first thread gets created, it starts executing, it
allocates the memory, prints the address and frees it. After first
thread finishes its execution, second thread starts. It allocates the
memory so allocator reuses the same chunk and you get same address.
If you put some sleep between malloc and free OR remove the free
statement itself as you did then you will get different addresses. So
this is really a timing issue when you do thread programming.
Hope this helps you understand the issue.
-Vinit
On Fri, Dec 25, 2009 at 12:11 AM, Randi Botse <nightdecoder@gmail.com> wrote:
> Hi all,
>
> I'm now learning thread reentrancy on Linux, so i write simple codes
> for demonstration:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <pthread.h>
>
> void *func(void *data)
> {
> char *ptr;
>
> ptr = malloc(8);
> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
> free(ptr);
> return NULL;
> }
>
> #define NTHREAD 5
>
> int main(void)
> {
> pthread_t thread[NTHREAD];
> int i;
>
> for (i = 0; i < NTHREAD; i++)
> if (pthread_create(&thread[i], NULL, func, (void*) &i))
> return -1;
> for (i = 0; i < NTHREAD; i++)
> pthread_join(thread[i], NULL);
> return 0;
> }
>
>
> I know the func() function is not reentrant, worst printf() debugging
> told me that's each thread pointer to character (ptr) may has same
> address, like this output:
>
> thread1 -> ptr at: 0x9a80128
> thread1 -> ptr at: 0x9a80138
> thread2 -> ptr at: 0x9a801d8
> thread4 -> ptr at: 0x9a801d8
> thread4 -> ptr at: 0x9a801d8
>
> I try to modify the func() by not free ptr to be:
>
> void *func(void *data)
> {
> char *ptr;
>
> ptr = malloc(8);
> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
> /* free(ptr); */
> return NULL;
> }
>
> And the result is i always got different address of each thread's ptr, such as:
>
> thread0 -> ptr at: 0x8db2098
> thread1 -> ptr at: 0x8db2138
> thread2 -> ptr at: 0x8db21d8
> thread3 -> ptr at: 0x8db2278
> thread4 -> ptr at: 0x8db2318
>
> Can you explain me why this happen? how about my printf() debugging
> method? it's works for this demonstration?
> Thanks before.
>
> - Randi
> --
> To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: thread: reentrant question
2009-12-24 19:30 ` vinit dhatrak
@ 2009-12-26 5:32 ` Randi Botse
2009-12-26 10:42 ` Michał Nazarewicz
2009-12-26 21:23 ` vinit dhatrak
0 siblings, 2 replies; 6+ messages in thread
From: Randi Botse @ 2009-12-26 5:32 UTC (permalink / raw)
To: vinit dhatrak; +Cc: linux-c-programming
Hi Vinit,
So, does this function actually reentrant when free() has not been
called?, thanks for your explanation.
Randi
On 12/25/09, vinit dhatrak <vinit.dhatrak@gmail.com> wrote:
> Hi Randi,
>
> You are observing this because of malloc's behaviour. If you allocate
> and free same-sized memory multiple times, then malloc tries to reuse
> the memory. You can try this by putting malloc/free statements in a
> loop.
>
> In your case, first thread gets created, it starts executing, it
> allocates the memory, prints the address and frees it. After first
> thread finishes its execution, second thread starts. It allocates the
> memory so allocator reuses the same chunk and you get same address.
>
> If you put some sleep between malloc and free OR remove the free
> statement itself as you did then you will get different addresses. So
> this is really a timing issue when you do thread programming.
>
> Hope this helps you understand the issue.
>
> -Vinit
>
> On Fri, Dec 25, 2009 at 12:11 AM, Randi Botse <nightdecoder@gmail.com>
> wrote:
>> Hi all,
>>
>> I'm now learning thread reentrancy on Linux, so i write simple codes
>> for demonstration:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <pthread.h>
>>
>> void *func(void *data)
>> {
>> char *ptr;
>>
>> ptr = malloc(8);
>> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
>> free(ptr);
>> return NULL;
>> }
>>
>> #define NTHREAD 5
>>
>> int main(void)
>> {
>> pthread_t thread[NTHREAD];
>> int i;
>>
>> for (i = 0; i < NTHREAD; i++)
>> if (pthread_create(&thread[i], NULL, func, (void*) &i))
>> return -1;
>> for (i = 0; i < NTHREAD; i++)
>> pthread_join(thread[i], NULL);
>> return 0;
>> }
>>
>>
>> I know the func() function is not reentrant, worst printf() debugging
>> told me that's each thread pointer to character (ptr) may has same
>> address, like this output:
>>
>> thread1 -> ptr at: 0x9a80128
>> thread1 -> ptr at: 0x9a80138
>> thread2 -> ptr at: 0x9a801d8
>> thread4 -> ptr at: 0x9a801d8
>> thread4 -> ptr at: 0x9a801d8
>>
>> I try to modify the func() by not free ptr to be:
>>
>> void *func(void *data)
>> {
>> char *ptr;
>>
>> ptr = malloc(8);
>> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
>> /* free(ptr); */
>> return NULL;
>> }
>>
>> And the result is i always got different address of each thread's ptr,
>> such as:
>>
>> thread0 -> ptr at: 0x8db2098
>> thread1 -> ptr at: 0x8db2138
>> thread2 -> ptr at: 0x8db21d8
>> thread3 -> ptr at: 0x8db2278
>> thread4 -> ptr at: 0x8db2318
>>
>> Can you explain me why this happen? how about my printf() debugging
>> method? it's works for this demonstration?
>> Thanks before.
>>
>> - Randi
>> --
>> To unsubscribe from this list: send the line "unsubscribe
>> linux-c-programming" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: thread: reentrant question
2009-12-26 5:32 ` Randi Botse
@ 2009-12-26 10:42 ` Michał Nazarewicz
2009-12-26 21:23 ` vinit dhatrak
1 sibling, 0 replies; 6+ messages in thread
From: Michał Nazarewicz @ 2009-12-26 10:42 UTC (permalink / raw)
To: Randi Botse; +Cc: vinit dhatrak, linux-c-programming
2009/12/26 Randi Botse <nightdecoder@gmail.com>:
> Hi Vinit,
>
> So, does this function actually reentrant when free() has not been
> called?, thanks for your explanation.
This function is reentrant both when free(3) is called and when
free(3) is not called (but it introduce memory leaks in the second
case).
As I've written before, the only issue may be with printf(3) as output
from various threads may get mixed together.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: thread: reentrant question
2009-12-26 5:32 ` Randi Botse
2009-12-26 10:42 ` Michał Nazarewicz
@ 2009-12-26 21:23 ` vinit dhatrak
2009-12-27 13:12 ` Randi Botse
1 sibling, 1 reply; 6+ messages in thread
From: vinit dhatrak @ 2009-12-26 21:23 UTC (permalink / raw)
To: Randi Botse; +Cc: linux-c-programming
On Sat, Dec 26, 2009 at 11:02 AM, Randi Botse <nightdecoder@gmail.com> wrote:
> Hi Vinit,
>
> So, does this function actually reentrant when free() has not been
> called?, thanks for your explanation.
>
> Randi
>
> On 12/25/09, vinit dhatrak <vinit.dhatrak@gmail.com> wrote:
>> Hi Randi,
>>
>> You are observing this because of malloc's behaviour. If you allocate
>> and free same-sized memory multiple times, then malloc tries to reuse
>> the memory. You can try this by putting malloc/free statements in a
>> loop.
>>
>> In your case, first thread gets created, it starts executing, it
>> allocates the memory, prints the address and frees it. After first
>> thread finishes its execution, second thread starts. It allocates the
>> memory so allocator reuses the same chunk and you get same address.
>>
>> If you put some sleep between malloc and free OR remove the free
>> statement itself as you did then you will get different addresses. So
>> this is really a timing issue when you do thread programming.
>>
>> Hope this helps you understand the issue.
>>
>> -Vinit
>>
>> On Fri, Dec 25, 2009 at 12:11 AM, Randi Botse <nightdecoder@gmail.com>
>> wrote:
>>> Hi all,
>>>
>>> I'm now learning thread reentrancy on Linux, so i write simple codes
>>> for demonstration:
>>>
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <pthread.h>
>>>
>>> void *func(void *data)
>>> {
>>> char *ptr;
>>>
>>> ptr = malloc(8);
>>> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
>>> free(ptr);
>>> return NULL;
>>> }
>>>
>>> #define NTHREAD 5
>>>
>>> int main(void)
>>> {
>>> pthread_t thread[NTHREAD];
>>> int i;
>>>
>>> for (i = 0; i < NTHREAD; i++)
>>> if (pthread_create(&thread[i], NULL, func, (void*) &i))
>>> return -1;
>>> for (i = 0; i < NTHREAD; i++)
>>> pthread_join(thread[i], NULL);
>>> return 0;
>>> }
>>>
>>>
>>> I know the func() function is not reentrant, worst printf() debugging
>>> told me that's each thread pointer to character (ptr) may has same
>>> address, like this output:
>>>
>>> thread1 -> ptr at: 0x9a80128
>>> thread1 -> ptr at: 0x9a80138
>>> thread2 -> ptr at: 0x9a801d8
>>> thread4 -> ptr at: 0x9a801d8
>>> thread4 -> ptr at: 0x9a801d8
>>>
>>> I try to modify the func() by not free ptr to be:
>>>
>>> void *func(void *data)
>>> {
>>> char *ptr;
>>>
>>> ptr = malloc(8);
>>> printf("thread%i -> ptr at: %p\n", *(int*) data, ptr);
>>> /* free(ptr); */
>>> return NULL;
>>> }
>>>
>>> And the result is i always got different address of each thread's ptr,
>>> such as:
>>>
>>> thread0 -> ptr at: 0x8db2098
>>> thread1 -> ptr at: 0x8db2138
>>> thread2 -> ptr at: 0x8db21d8
>>> thread3 -> ptr at: 0x8db2278
>>> thread4 -> ptr at: 0x8db2318
>>>
>>> Can you explain me why this happen? how about my printf() debugging
>>> method? it's works for this demonstration?
>>> Thanks before.
>>>
>>> - Randi
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe
>>> linux-c-programming" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>>
>
Hi Randi,
malloc is thread-safe function in case of posix threads used by gcc
(-lpthread option). So your function is fine. You dont have to worry
about what memory each thread will allocate, even if free() is used or
not. Its taken care in malloc/free implementation.
Here is the discussion about this issue,
http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/2431a99b9bdcef11/ea800579e40f7fa4
-Vinit
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: thread: reentrant question
2009-12-26 21:23 ` vinit dhatrak
@ 2009-12-27 13:12 ` Randi Botse
0 siblings, 0 replies; 6+ messages in thread
From: Randi Botse @ 2009-12-27 13:12 UTC (permalink / raw)
To: vinit dhatrak; +Cc: mina86, linux-c-programming
Thanks all for your times. It help me so much.
Randi
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-12-27 13:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-24 18:41 thread: reentrant question Randi Botse
2009-12-24 19:30 ` vinit dhatrak
2009-12-26 5:32 ` Randi Botse
2009-12-26 10:42 ` Michał Nazarewicz
2009-12-26 21:23 ` vinit dhatrak
2009-12-27 13:12 ` Randi Botse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).