Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming.threads > #677 > unrolled thread
| Started by | Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> |
|---|---|
| First post | 2011-11-21 03:29 +0000 |
| Last post | 2011-11-22 21:06 +0100 |
| Articles | 13 — 8 participants |
Back to article view | Back to comp.programming.threads
Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> - 2011-11-21 03:29 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Ian Collins <ian-news@hotmail.com> - 2011-11-21 20:00 +1300
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Marcel Müller <news.5.maazl@spamgourmet.com> - 2011-11-21 08:48 +0100
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> - 2011-11-21 07:56 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Ian Collins <ian-news@hotmail.com> - 2011-11-21 21:01 +1300
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? David Schwartz <davids@webmaster.com> - 2011-11-21 12:06 -0800
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> - 2011-11-21 20:30 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Casper H.S. Dik <Casper.Dik@OrSPaMcle.COM> - 2011-11-21 23:07 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> - 2011-11-22 05:31 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-11-25 17:49 +0000
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? David Schwartz <davids@webmaster.com> - 2011-11-23 12:53 -0800
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? Robert Wessel <robertwessel2@yahoo.com> - 2011-11-21 02:28 -0600
Re: Is pthread_create( id, 0, f, &something_on_my_stack ); safe? "Ersek, Laszlo" <lacos@caesar.elte.hu> - 2011-11-22 21:06 +0100
| From | Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> |
|---|---|
| Date | 2011-11-21 03:29 +0000 |
| Subject | Is pthread_create( id, 0, f, &something_on_my_stack ); safe? |
| Message-ID | <4EC9C581.405E@2ndquadrant.com> |
Hi all,
Given
void *f( void *j )
{
int i = *((int *)j);
//..
}
void g( void )
{
pthread_t *id = ...;
int something_on_my_stack = 42; // Life, universe & everything
pthread_create( id, 0, f, &something_on_my_stack );
is there any guarantee the value has been copied to f()s stack by the
time pthread_create() returns?
Or, to be a little bit more explicit, is there anything I can use for
safe argument passing to newly created threads without allocating new
memory and (presumably) have the threads free it?
My current design calls for two integers passed to the newly created
threads. I want something both safe and clean. That is, minimum of
code clutter.
--
Johann Oskarsson http://www.2ndquadrant.com/ |[]
PostgreSQL Development, 24x7 Support, Training and Services --+--
|
Blog: http://my.opera.com/myrkraverk/blog/
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-11-21 20:00 +1300 |
| Message-ID | <9iub8jF7g0U1@mid.individual.net> |
| In reply to | #677 |
On 11/21/11 04:29 PM, Johann 'Myrkraverk' Oskarsson wrote:
> Hi all,
>
> Given
>
> void *f( void *j )
> {
> int i = *((int *)j);
> //..
> }
>
> void g( void )
> {
> pthread_t *id = ...;
> int something_on_my_stack = 42; // Life, universe& everything
> pthread_create( id, 0, f,&something_on_my_stack );
>
> is there any guarantee the value has been copied to f()s stack by the
> time pthread_create() returns?
No.
> Or, to be a little bit more explicit, is there anything I can use for
> safe argument passing to newly created threads without allocating new
> memory and (presumably) have the threads free it?
I can't see any problem with
static int something_on_my_stack = 42;
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Marcel Müller <news.5.maazl@spamgourmet.com> |
|---|---|
| Date | 2011-11-21 08:48 +0100 |
| Message-ID | <4eca026a$0$6570$9b4e6d93@newsspool3.arcor-online.net> |
| In reply to | #678 |
On 21.11.2011 08:00, Ian Collins wrote: > I can't see any problem with > > static int something_on_my_stack = 42; Except that is no longer reentrant and you cannot run more than one thread in parallel this way. The common way is to allocate something on the heap. Marcel
[toc] | [prev] | [next] | [standalone]
| From | Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> |
|---|---|
| Date | 2011-11-21 07:56 +0000 |
| Message-ID | <x6zkfp52nx.fsf@2ndquadrant.com> |
| In reply to | #678 |
Ian Collins <ian-news@hotmail.com> writes:
Thank you.
> On 11/21/11 04:29 PM, Johann 'Myrkraverk' Oskarsson wrote:
>> Or, to be a little bit more explicit, is there anything I can use
>> for safe argument passing to newly created threads without
>> allocating new memory and (presumably) have the threads free it?
>
> I can't see any problem with
>
> static int something_on_my_stack = 42;
Unfortunately, the numbers are retrieved in a loop. To be extra ex-
plicit, file descriptors from accept(), pipe() and friends. I can't
see any way that does not involve either 1) memory allocation/freeing
or 2) synchronization. Both seem unnecessary code bloat for such a
simple task.
I did not see it at the first glance at the FAQ.
--
Johann Oskarsson http://www.2ndquadrant.com/ |[]
PostgreSQL Development, 24x7 Support, Training and Services --+--
|
Blog: http://my.opera.com/myrkraverk/blog/
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-11-21 21:01 +1300 |
| Message-ID | <9iuer1F7g0U2@mid.individual.net> |
| In reply to | #680 |
On 11/21/11 08:56 PM, Johann 'Myrkraverk' Oskarsson wrote: > Ian Collins<ian-news@hotmail.com> writes: > > Thank you. > >> On 11/21/11 04:29 PM, Johann 'Myrkraverk' Oskarsson wrote: >>> Or, to be a little bit more explicit, is there anything I can use >>> for safe argument passing to newly created threads without >>> allocating new memory and (presumably) have the threads free it? >> >> I can't see any problem with >> >> static int something_on_my_stack = 42; > > Unfortunately, the numbers are retrieved in a loop. To be extra ex- > plicit, file descriptors from accept(), pipe() and friends. I can't > see any way that does not involve either 1) memory allocation/freeing > or 2) synchronization. Both seem unnecessary code bloat for such a > simple task. Dynamic allocation is the idiomatic solution for any non-trivial situation. Sometimes extra complexity is unavoidable. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-11-21 12:06 -0800 |
| Message-ID | <cae6c8c3-6406-485e-8cc2-7cda775a5f8d@h31g2000pro.googlegroups.com> |
| In reply to | #680 |
On Nov 20, 11:56 pm, Johann 'Myrkraverk' Oskarsson <joh...@2ndquadrant.com> wrote: > Unfortunately, the numbers are retrieved in a loop. To be extra ex- > plicit, file descriptors from accept(), pipe() and friends. I can't > see any way that does not involve either 1) memory allocation/freeing > or 2) synchronization. Both seem unnecessary code bloat for such a > simple task. Here are the choices you have rejected: 1) Holding the value around until you are sure the new thread is done with it (synchronization). 2) Giving the new thread its own copy so it can use it at its leisure (memory allocating). Even at a high level of generality, what could a third alternative look like? Your son needs a car. Either you share yours with him (option 1) or you get him his own (option 2). What's the third choice? DS
[toc] | [prev] | [next] | [standalone]
| From | Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> |
|---|---|
| Date | 2011-11-21 20:30 +0000 |
| Message-ID | <x662id43re.fsf@2ndquadrant.com> |
| In reply to | #683 |
David Schwartz <davids@webmaster.com> writes:
> On Nov 20, 11:56 pm, Johann 'Myrkraverk' Oskarsson
> <joh...@2ndquadrant.com> wrote:
>
>> Unfortunately, the numbers are retrieved in a loop. To be extra
>> ex- plicit, file descriptors from accept(), pipe() and friends. I
>> can't see any way that does not involve either 1) memory
>> allocation/freeing or 2) synchronization. Both seem unnecessary
>> code bloat for such a simple task.
>
> Here are the choices you have rejected:
I did not reject them. Both apply code overhead (as in, I write more
code) I have to maintain. The more code I can get rid of the better.
> Your son needs a car. Either you share yours with him (option 1) or
> you get him his own (option 2). What's the third choice?
He buys his own.
--
Johann Oskarsson http://www.2ndquadrant.com/ |[]
PostgreSQL Development, 24x7 Support, Training and Services --+--
|
Blog: http://my.opera.com/myrkraverk/blog/
[toc] | [prev] | [next] | [standalone]
| From | Casper H.S. Dik <Casper.Dik@OrSPaMcle.COM> |
|---|---|
| Date | 2011-11-21 23:07 +0000 |
| Message-ID | <4ecad9c6$0$6961$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #684 |
Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> writes: >David Schwartz <davids@webmaster.com> writes: >> On Nov 20, 11:56 pm, Johann 'Myrkraverk' Oskarsson >> <joh...@2ndquadrant.com> wrote: >> >>> Unfortunately, the numbers are retrieved in a loop. To be extra >>> ex- plicit, file descriptors from accept(), pipe() and friends. I >>> can't see any way that does not involve either 1) memory >>> allocation/freeing or 2) synchronization. Both seem unnecessary >>> code bloat for such a simple task. >> >> Here are the choices you have rejected: >I did not reject them. Both apply code overhead (as in, I write more >code) I have to maintain. The more code I can get rid of the better. If it's only one fd, cast it to a pointer and use the pointer as an integer; there is really no reason to interpret the pointer as a pointer, right? Casper --
[toc] | [prev] | [next] | [standalone]
| From | Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> |
|---|---|
| Date | 2011-11-22 05:31 +0000 |
| Message-ID | <x6zkfo3epe.fsf@2ndquadrant.com> |
| In reply to | #685 |
Casper H.S. Dik <Casper.Dik@OrSPaMcle.COM> writes:
> If it's only one fd, cast it to a pointer and use the pointer as an
> integer; there is really no reason to interpret the pointer as a
> pointer, right?
Alas, it's two or I'd probably do this. I *might* restrict myself to
64bit compilations and encode the two integers in one pointer but
that's just silly and gains me nothing in maintainability.
Or I can "assume" the file descriptors are low and encode them both in
the same integer. But that's even more silly and a maintenance
nightmare.
--
Johann Oskarsson http://www.2ndquadrant.com/ |[]
PostgreSQL Development, 24x7 Support, Training and Services --+--
|
Blog: http://my.opera.com/myrkraverk/blog/
[toc] | [prev] | [next] | [standalone]
| From | blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> |
|---|---|
| Date | 2011-11-25 17:49 +0000 |
| Message-ID | <9ja2ooFmj4U2@mid.individual.net> |
| In reply to | #685 |
In article <4ecad9c6$0$6961$e4fe514c@news2.news.xs4all.nl>, Casper H.S. Dik <Casper.Dik@OrSPaMcle.COM> wrote: > Johann 'Myrkraverk' Oskarsson <johann@2ndquadrant.com> writes: > > >David Schwartz <davids@webmaster.com> writes: > > >> On Nov 20, 11:56 pm, Johann 'Myrkraverk' Oskarsson > >> <joh...@2ndquadrant.com> wrote: > >> > >>> Unfortunately, the numbers are retrieved in a loop. To be extra > >>> ex- plicit, file descriptors from accept(), pipe() and friends. I > >>> can't see any way that does not involve either 1) memory > >>> allocation/freeing or 2) synchronization. Both seem unnecessary > >>> code bloat for such a simple task. > >> > >> Here are the choices you have rejected: > > >I did not reject them. Both apply code overhead (as in, I write more > >code) I have to maintain. The more code I can get rid of the better. > > > If it's only one fd, cast it to a pointer and use the pointer as an > integer; there is really no reason to interpret the pointer as a > pointer, right? > There was a discussion of this topic in comp.lang.c recently: http://groups.google.com/group/comp.lang.c/browse_thread/thread/9ce104bbf47d3fbc/c96cd19501ef372b?hl=en&q=#c96cd19501ef372b I'm not sure it reached consensus, but the arguments against this "use the pointer parameter to pass an integer" approach seemed to boil down to "not guaranteed to work on all platforms" and "likely to confuse other readers of the code". To me the latter alone is a good reason to avoid it, but -- <shrug>. -- B. L. Massingill ObDisclaimer: I don't speak for my employers; they return the favor.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-11-23 12:53 -0800 |
| Message-ID | <8095043a-460b-4fd1-aa45-ae00da2aec7f@u10g2000prl.googlegroups.com> |
| In reply to | #684 |
On Nov 21, 12:30 pm, Johann 'Myrkraverk' Oskarsson <joh...@2ndquadrant.com> wrote: > > Your son needs a car. Either you share yours with him (option 1) or > > you get him his own (option 2). What's the third choice? > > He buys his own. Well, yeah, that works in the hypothetical. But that wouldn't work in this case. He wouldn't know what car to buy unless you wait until he's finished buying a car, which is the synchronization you rejected. DS
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2011-11-21 02:28 -0600 |
| Message-ID | <hb2kc7hlrv0d2if3a8jcqvqrn1ghtafroq@4ax.com> |
| In reply to | #677 |
On Mon, 21 Nov 2011 03:29:05 +0000, Johann 'Myrkraverk' Oskarsson
<johann@2ndquadrant.com> wrote:
>Hi all,
>
>Given
>
> void *f( void *j )
> {
> int i = *((int *)j);
> //..
> }
>
> void g( void )
> {
> pthread_t *id = ...;
> int something_on_my_stack = 42; // Life, universe & everything
> pthread_create( id, 0, f, &something_on_my_stack );
>
>is there any guarantee the value has been copied to f()s stack by the
>time pthread_create() returns?
>
>Or, to be a little bit more explicit, is there anything I can use for
>safe argument passing to newly created threads without allocating new
>memory and (presumably) have the threads free it?
>
>My current design calls for two integers passed to the newly created
>threads. I want something both safe and clean. That is, minimum of
>code clutter.
Nothing really, in general. Just allocate the memory and pass a
pointer to that. It's simple, it works.
On occasion, it's reasonable to have the created thread post a
semaphore that the creator is waiting on, when the referenced items
are no longer needed. That usually goes with needing to wait until
the created thread has started successfully (and is now ready to do
what ever it is it does), and having a large amount of startup data.
Of course in this case, you're now stuck passing the semaphore plus
the other data to the created thread, and that's going to be more work
than passing a couple of ints.
[toc] | [prev] | [next] | [standalone]
| From | "Ersek, Laszlo" <lacos@caesar.elte.hu> |
|---|---|
| Date | 2011-11-22 21:06 +0100 |
| Message-ID | <Pine.LNX.4.64.1111222033040.25836@login03.caesar.elte.hu> |
| In reply to | #677 |
On Mon, 21 Nov 2011, Johann 'Myrkraverk' Oskarsson wrote:
> Hi all,
>
> Given
>
> void *f( void *j )
> {
> int i = *((int *)j);
> //..
> }
>
> void g( void )
> {
> pthread_t *id = ...;
> int something_on_my_stack = 42; // Life, universe & everything
> pthread_create( id, 0, f, &something_on_my_stack );
>
> is there any guarantee the value has been copied to f()s stack by the
> time pthread_create() returns?
>
> Or, to be a little bit more explicit, is there anything I can use for
> safe argument passing to newly created threads without allocating new
> memory and (presumably) have the threads free it?
>
> My current design calls for two integers passed to the newly created
> threads. I want something both safe and clean. That is, minimum of
> code clutter.
If you don't need more than num_threads threads at any time:
static struct thread_arg
{
int fd1,
fd2;
} thread_arg[num_threads];
If you start a low fixed number of threads per core, this could work. (If
you start threads for code organization purposes, not so much.) Just
before (re-)starting thread #n (0 <= n < num_threads), fill in
thread_arg[n], and pass &thread_arg[n] (written differently, thread_arg +
n) to the start function. If necessary for other purposes, the thread can
derive its own number from the arg address: (struct thread_arg *)arg -
thread_arg.
If num_threads is not known at compile time, perhaps you could afford a
single malloc() for the full array (and store the address in a "global"
pointer). In C99 you might use a VLA that belongs to a block outliving all
worker threads. As in:
struct thread_arg
{
unsigned thread_nr;
int fd1,
fd2;
};
int
main(int argc, char **argv)
{
unsigned num_threads;
get_num_threads(&num_threads, argc, argv);
{
struct thread_arg thread_arg[num_threads];
pthread_t worker[num_threads];
unsigned u;
for (u = 0u; u < num_threads; ++u) {
struct thread_arg *cur;
cur = thread_arg + u;
cur->thread_nr = u;
cur->fd1 = ...;
cur->fd2 = ...;
pthread_create(worker + u, 0, start_func, cur);
}
/* do whatever the "main thread" does */
/* join all workers before thread_arg goes out of scope & life */
for (u = 0u; u < num_threads; ++u) {
pthread_join(worker[u], 0);
}
}
return 0;
}
Laszlo
[toc] | [prev] | [standalone]
Back to top | Article view | comp.programming.threads
csiph-web