Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #120911 > unrolled thread

How to make the Process ctor work for different R type?

Started bywij <wyniijj5@gmail.com>
First post2024-11-19 10:38 +0800
Last post2024-11-22 00:32 +0800
Articles 20 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-19 10:38 +0800
    Re: How to make the Process ctor work for different R type? red floyd <no.spam.here@its.invalid> - 2024-11-18 20:34 -0800
      Re: How to make the Process ctor work for different R type? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-11-19 01:04 -0500
        Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-19 08:27 +0000
          Re: How to make the Process ctor work for different R type? Paavo Helde <eesnimi@osa.pri.ee> - 2024-11-19 10:45 +0200
            Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-19 09:15 +0000
        Re: How to make the Process ctor work for different R type? red floyd <no.spam.here@its.invalid> - 2024-11-20 07:23 -0800
          Re: How to make the Process ctor work for different R type? scott@slp53.sl.home (Scott Lurndal) - 2024-11-20 15:47 +0000
    Re: How to make the Process ctor work for different R         type? Sam <sam@email-scan.com> - 2024-11-19 07:07 -0500
      Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-19 21:16 +0800
        Re: How to make the Process ctor work for different R type? Paavo Helde <eesnimi@osa.pri.ee> - 2024-11-19 16:15 +0200
        Re: How to make the Process ctor work for different R         type? Sam <sam@email-scan.com> - 2024-11-20 07:51 -0500
    Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-19 16:13 +0100
      Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-20 00:30 +0800
        Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-19 17:42 +0100
          Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-21 15:27 +0100
            Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-21 16:11 +0000
              Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-21 17:59 +0100
                Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-22 09:54 +0000
            Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-22 00:32 +0800

#120911 — How to make the Process ctor work for different R type?

Fromwij <wyniijj5@gmail.com>
Date2024-11-19 10:38 +0800
SubjectHow to make the Process ctor work for different R type?
Message-ID<c7d5064e0ec2f7720f1b6cef381666cfbf249cdb.camel@gmail.com>
struct Process {
    template<typename R>
    explicit Process(R (*pfunc)(), bool ret_int=false) {
      int pid= fork();
      if(pid==-1) {
        throw "Error";
      }
      if(pid==0) {
        if(ret_int) {
          _exit( pfunc() ); // error: invalid use of void expression
        } else {
          pfunc();         // ret value ignored
          _exit(0);
        }
      }
    };
}

The issue is _exit(int) require int type.

void f();
Process proc(f);   // error: R is void

So, how to make the Process ctor work for different R type?



[toc] | [next] | [standalone]


#120912

Fromred floyd <no.spam.here@its.invalid>
Date2024-11-18 20:34 -0800
Message-ID<vhh4h4$1mb2b$1@redfloyd.dont-email.me>
In reply to#120911
On 11/18/2024 6:38 PM, wij wrote:
> struct Process {
>      template<typename R>
>      explicit Process(R (*pfunc)(), bool ret_int=false) {
>        int pid= fork();
>        if(pid==-1) {
>          throw "Error";
>        }
>        if(pid==0) {
>          if(ret_int) {
>            _exit( pfunc() ); // error: invalid use of void expression
>          } else {
>            pfunc();         // ret value ignored
>            _exit(0);
>          }
>        }
>      };
> }
> 
> The issue is _exit(int) require int type.
> 
> void f();
> Process proc(f);   // error: R is void
> 
> So, how to make the Process ctor work for different R type?
> 

Google for "template specialization".

Also, use exit(), not _exit().  The former is ISO C++, the latter
is not.

[toc] | [prev] | [next] | [standalone]


#120913

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2024-11-19 01:04 -0500
Message-ID<vhh9p7$1mspa$1@dont-email.me>
In reply to#120912
On 11/18/24 23:34, red floyd wrote:
...
> Also, use exit(), not _exit().  The former is ISO C++, the latter
> is not.

Note, however, that _Exit() has been part of ISO C++'s version of the C
standard library since 2011. It was originally added in C99, and _exit()
was added to POSIX in 2001, and is defined as equivalent to _Exit().

[toc] | [prev] | [next] | [standalone]


#120914

FromMuttley@DastartdlyHQ.org
Date2024-11-19 08:27 +0000
Message-ID<vhhi5d$1ohbv$1@dont-email.me>
In reply to#120913
On Tue, 19 Nov 2024 01:04:23 -0500
James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled:
>On 11/18/24 23:34, red floyd wrote:
>....
>> Also, use exit(), not _exit().  The former is ISO C++, the latter
>> is not.
>
>Note, however, that _Exit() has been part of ISO C++'s version of the C
>standard library since 2011. It was originally added in C99, and _exit()
>was added to POSIX in 2001, and is defined as equivalent to _Exit().

exit() flushes buffers before the process exits (in *nix, don't know about
windows), _exit() doesn't.

[toc] | [prev] | [next] | [standalone]


#120915

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2024-11-19 10:45 +0200
Message-ID<vhhj7d$1ojsj$1@dont-email.me>
In reply to#120914
On 19.11.2024 10:27, Muttley@DastartdlyHQ.org wrote:
> On Tue, 19 Nov 2024 01:04:23 -0500
> James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled:
>> On 11/18/24 23:34, red floyd wrote:
>> ....
>>> Also, use exit(), not _exit().  The former is ISO C++, the latter
>>> is not.
>>
>> Note, however, that _Exit() has been part of ISO C++'s version of the C
>> standard library since 2011. It was originally added in C99, and _exit()
>> was added to POSIX in 2001, and is defined as equivalent to _Exit().
> 
> exit() flushes buffers before the process exits (in *nix, don't know about
> windows), _exit() doesn't.
> 

Even more importantly, exit() executes the destructors of static objects 
and atexit handlers, whereas _exit() does not. So, _exit() is only 
suitable for emergency exit in case of errors (failing to join all child 
threads, for example).

[toc] | [prev] | [next] | [standalone]


#120916

FromMuttley@DastartdlyHQ.org
Date2024-11-19 09:15 +0000
Message-ID<vhhkvj$1p1a7$1@dont-email.me>
In reply to#120915
On Tue, 19 Nov 2024 10:45:34 +0200
Paavo Helde <eesnimi@osa.pri.ee> boring babbled:
>On 19.11.2024 10:27, Muttley@DastartdlyHQ.org wrote:
>> On Tue, 19 Nov 2024 01:04:23 -0500
>> James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled:
>>> On 11/18/24 23:34, red floyd wrote:
>>> ....
>>>> Also, use exit(), not _exit().  The former is ISO C++, the latter
>>>> is not.
>>>
>>> Note, however, that _Exit() has been part of ISO C++'s version of the C
>>> standard library since 2011. It was originally added in C99, and _exit()
>>> was added to POSIX in 2001, and is defined as equivalent to _Exit().
>> 
>> exit() flushes buffers before the process exits (in *nix, don't know about
>> windows), _exit() doesn't.
>> 
>
>Even more importantly, exit() executes the destructors of static objects 
>and atexit handlers, whereas _exit() does not. So, _exit() is only 

But doesn't call the destructors of objects on the stack which IMO makes it
a fairly useless halfway house. Either call all or don't call any.

>suitable for emergency exit in case of errors (failing to join all child 
>threads, for example).

Or a system shutdown where you just want to do the most important save 
functions then immediately die.

[toc] | [prev] | [next] | [standalone]


#120941

Fromred floyd <no.spam.here@its.invalid>
Date2024-11-20 07:23 -0800
Message-ID<vhkut6$59pn$1@redfloyd.dont-email.me>
In reply to#120913
On 11/18/2024 10:04 PM, James Kuyper wrote:
> On 11/18/24 23:34, red floyd wrote:
> ...
>> Also, use exit(), not _exit().  The former is ISO C++, the latter
>> is not.
> 
> Note, however, that _Exit() has been part of ISO C++'s version of the C
> standard library since 2011. It was originally added in C99, and _exit()
> was added to POSIX in 2001, and is defined as equivalent to _Exit().
Thank you.  I was unaware of that.

[toc] | [prev] | [next] | [standalone]


#120943

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-11-20 15:47 +0000
Message-ID<kwn%O.4462$rXyb.2827@fx48.iad>
In reply to#120941
red floyd <no.spam.here@its.invalid> writes:
>On 11/18/2024 10:04 PM, James Kuyper wrote:
>> On 11/18/24 23:34, red floyd wrote:
>> ...
>>> Also, use exit(), not _exit().  The former is ISO C++, the latter
>>> is not.
>> 
>> Note, however, that _Exit() has been part of ISO C++'s version of the C
>> standard library since 2011. It was originally added in C99, and _exit()
>> was added to POSIX in 2001, and is defined as equivalent to _Exit().
>Thank you.  I was unaware of that.

POSIX also has quick_exit(), which doesn't call the registered atexit
hooks, but does call registered quick_atexit hooks.

[toc] | [prev] | [next] | [standalone]


#120917 — Re: How to make the Process ctor work for different R type?

FromSam <sam@email-scan.com>
Date2024-11-19 07:07 -0500
SubjectRe: How to make the Process ctor work for different R type?
Message-ID<cone.1732018068.32867.86903.1000@ripper.email-scan.com>
In reply to#120911
wij writes:

> struct Process {
>     template<typename R>
>     explicit Process(R (*pfunc)(), bool ret_int=false) {
>       int pid= fork();
>       if(pid==-1) {
>         throw "Error";
>       }
>       if(pid==0) {
>         if(ret_int) {
>           _exit( pfunc() ); // error: invalid use of void expression
>         } else {
>           pfunc();         // ret value ignored
>           _exit(0);
>         }
>       }
>     };
> }
>
> The issue is _exit(int) require int type.
>
> void f();
> Process proc(f);   // error: R is void
>
> So, how to make the Process ctor work for different R type?

For starters this has to be resolved at compile time, not run time.  
Therefore you can't use ret_int, whose purpose is very obvious, because you  
don't know its value until runtime. Just because it has a default value  
doesn't turn it into a compile-time, constexpr value.

Fortunately there is a very convenient R here. So the first step is to get  
rid of the useless `ret_int`.

    template<typename R>
    explicit Process(R (*pfunc)()) {

And now this becomes a boring case of constexpr if:

#include <type_traits>

// …


    if constexpr(!std::is_same_v<R,void>)
      _exit( pfunc() );
    } else {
         pfunc();
         _exit(0);
    }

[toc] | [prev] | [next] | [standalone]


#120919

Fromwij <wyniijj5@gmail.com>
Date2024-11-19 21:16 +0800
Message-ID<01b48b009dae2e61e8c73bb09dcd9bdff90ba26a.camel@gmail.com>
In reply to#120917
On Tue, 2024-11-19 at 07:07 -0500, Sam wrote:
> wij writes:
> 
> > struct Process {
> >     template<typename R>
> >     explicit Process(R (*pfunc)(), bool ret_int=false) {
> >       int pid= fork();
> >       if(pid==-1) {
> >         throw "Error";
> >       }
> >       if(pid==0) {
> >         if(ret_int) {
> >           _exit( pfunc() ); // error: invalid use of void expression
> >         } else {
> >           pfunc();         // ret value ignored
> >           _exit(0);
> >         }
> >       }
> >     };
> > }
> > 
> > The issue is _exit(int) require int type.
> > 
> > void f();
> > Process proc(f);   // error: R is void
> > 
> > So, how to make the Process ctor work for different R type?
> 
> For starters this has to be resolved at compile time, not run time.  
> Therefore you can't use ret_int, whose purpose is very obvious, because you  
> don't know its value until runtime. Just because it has a default value  
> doesn't turn it into a compile-time, constexpr value.
> 
> Fortunately there is a very convenient R here. So the first step is to get  
> rid of the useless `ret_int`.
> 
>     template<typename R>
>     explicit Process(R (*pfunc)()) {
> 
> And now this becomes a boring case of constexpr if:
> 
> #include <type_traits>
> 
> // …
> 
> 
>     if constexpr(!std::is_same_v<R,void>)
>       _exit( pfunc() );
>     } else {
>          pfunc();
>          _exit(0);
>     }

Thanks. I need C++11 way.

[toc] | [prev] | [next] | [standalone]


#120921

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2024-11-19 16:15 +0200
Message-ID<vhi6i1$1s8lf$1@dont-email.me>
In reply to#120919
On 19.11.2024 15:16, wij wrote:
> On Tue, 2024-11-19 at 07:07 -0500, Sam wrote:
>> wij writes:
>>
>>> struct Process {
>>>      template<typename R>
>>>      explicit Process(R (*pfunc)(), bool ret_int=false) {
>>>        int pid= fork();
>>>        if(pid==-1) {
>>>          throw "Error";
>>>        }
>>>        if(pid==0) {
>>>          if(ret_int) {
>>>            _exit( pfunc() ); // error: invalid use of void expression
>>>          } else {
>>>            pfunc();         // ret value ignored
>>>            _exit(0);
>>>          }
>>>        }
>>>      };
>>> }
>>>
>>> The issue is _exit(int) require int type.
>>>
>>> void f();
>>> Process proc(f);   // error: R is void
>>>
>>> So, how to make the Process ctor work for different R type?
>>
>> For starters this has to be resolved at compile time, not run time.
>> Therefore you can't use ret_int, whose purpose is very obvious, because you
>> don't know its value until runtime. Just because it has a default value
>> doesn't turn it into a compile-time, constexpr value.
>>
>> Fortunately there is a very convenient R here. So the first step is to get
>> rid of the useless `ret_int`.
>>
>>      template<typename R>
>>      explicit Process(R (*pfunc)()) {
>>
>> And now this becomes a boring case of constexpr if:
>>
>> #include <type_traits>
>>
>> // …
>>
>>
>>      if constexpr(!std::is_same_v<R,void>)
>>        _exit( pfunc() );
>>      } else {
>>           pfunc();
>>           _exit(0);
>>      }
> 
> Thanks. I need C++11 way.

struct Process {
     template<typename FUNC>
     explicit Process(FUNC func) {
         int pid = fork();
         if (pid == -1) {
             throw "Error";
         }
         if (pid == 0) {
             _exit(func());
         }
     }
};

int g() {return 1;}

void f() {}

int main() {

     Process proc1(g);

     Process proc2([]() {f(); return 0; });

}

[toc] | [prev] | [next] | [standalone]


#120934 — Re: How to make the Process ctor work for different R type?

FromSam <sam@email-scan.com>
Date2024-11-20 07:51 -0500
SubjectRe: How to make the Process ctor work for different R type?
Message-ID<cone.1732107086.53104.104235.1000@ripper.email-scan.com>
In reply to#120919
wij writes:

> >
> >     if constexpr(!std::is_same_v<R,void>)
> >       _exit( pfunc() );
> >     } else {
> >          pfunc();
> >          _exit(0);
> >     }
>
> Thanks. I need C++11 way.

The C++11 way would involve using specialization, and some major  
refactoring, to avoid code duplication.

     explicit Process::Process<void>(void (*pfunc)()) {

followed by a specialization declaration:

     template<> explicit Process::Process<void>(void (*pfunc)()) {

And, as I mentioned, the common code would need to be factored out, in some  
way, to avoid duplication.

Updating the compiler to something less than a decade old will probably be  
much easier.

I thought about using a delegating constructor, something like:

template<> explicit Process::Process<void>(void (*pfunc)())
   : Process([&]{ pfunc(); return 0; })
{
}

but this wouldn't work for the obvious reason. One could try to get this to  
work with a std::function, although I think this would be somewhat tricky  
for overload resolution to work correctly.

[toc] | [prev] | [next] | [standalone]


#120922

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-11-19 16:13 +0100
Message-ID<vhi9s8$1t262$1@raubtier-asyl.eternal-september.org>
In reply to#120911
Am 19.11.2024 um 03:38 schrieb wij:
> struct Process {
>      template<typename R>
>      explicit Process(R (*pfunc)(), bool ret_int=false) {
>        int pid= fork();
>        if(pid==-1) {
>          throw "Error";
>        }
>        if(pid==0) {
>          if(ret_int) {
>            _exit( pfunc() ); // error: invalid use of void expression
>          } else {
>            pfunc();         // ret value ignored
>            _exit(0);
>          }
>        }
>      };
> }

Why do you need a generic return of the callback where you don't
use it ? Use a function<void ()> const & parameter for pfunc so
that you can attach an arbitrary C-function or lambda.

[toc] | [prev] | [next] | [standalone]


#120924

Fromwij <wyniijj5@gmail.com>
Date2024-11-20 00:30 +0800
Message-ID<c61944ca5039ccb36cb32f792c69e79a144107c7.camel@gmail.com>
In reply to#120922
On Tue, 2024-11-19 at 16:13 +0100, Bonita Montero wrote:
> Am 19.11.2024 um 03:38 schrieb wij:
> > struct Process {
> >      template<typename R>
> >      explicit Process(R (*pfunc)(), bool ret_int=false) {
> >        int pid= fork();
> >        if(pid==-1) {
> >          throw "Error";
> >        }
> >        if(pid==0) {
> >          if(ret_int) {
> >            _exit( pfunc() ); // error: invalid use of void expression
> >          } else {
> >            pfunc();         // ret value ignored
> >            _exit(0);
> >          }
> >        }
> >      };
> > }
> 
> Why do you need a generic return of the callback where you don't
> use it ? Use a function<void ()> const & parameter for pfunc so
> that you can attach an arbitrary C-function or lambda.

Not sure what you are talking about (callback???).
The current function for ForkProcess to fork has to retun int (or convertible)
or Error (overloaded). Because, other types may not be sensible.

[toc] | [prev] | [next] | [standalone]


#120925

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-11-19 17:42 +0100
Message-ID<vhif3n$1u1va$1@raubtier-asyl.eternal-september.org>
In reply to#120924
>> Am 19.11.2024 um 03:38 schrieb wij:

>>> struct Process {
>>>       template<typename R>
>>>       explicit Process(R (*pfunc)(), bool ret_int=false) {
>>>         int pid= fork();
>>>         if(pid==-1) {
>>>           throw "Error";
>>>         }
>>>         if(pid==0) {
>>>           if(ret_int) {
>>>             _exit( pfunc() ); // error: invalid use of void expression
>>>           } else {
>>>             pfunc();         // ret value ignored
>>>             _exit(0);
>>>           }
>>>         }
>>>       };
>>> }

How about that:

struct Process
{
	template<typename Fn>
	Process( Fn fn )
	{
		int pid = fork();
		if( pid == -1 )
			throw system_error( errno, system_category(), "fork failed" );
		if( pid )
			return;
		if constexpr( same_as<invoke_result_t<Fn>, int> )
			exit( fn() );
		else
		{
			fn();
			exit( 0 );
		}
	}
};

[toc] | [prev] | [next] | [standalone]


#120963

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-11-21 15:27 +0100
Message-ID<vhnfvo$m1p1$1@raubtier-asyl.eternal-september.org>
In reply to#120925
But a proper C++-ish wrapper would look like this:

template<typename Fn>
void xfork( Fn &&&fn )
{
	int pid = fork();
	if( pid == -1 )
		throw system_error( errno, system_category(), "fork failed" );
	if( pid )
		return;
	if constexpr( same_as<invoke_result_t<Fn>, int> )
		exit( fn() );
	else
	{
		fn();
		exit( 0 );
	}
}

There's no need for a process wrapper class if you fork only.

[toc] | [prev] | [next] | [standalone]


#120966

FromMuttley@DastartdlyHQ.org
Date2024-11-21 16:11 +0000
Message-ID<vhnm4a$n66i$1@dont-email.me>
In reply to#120963
On Thu, 21 Nov 2024 15:27:59 +0100
Bonita Montero <Bonita.Montero@gmail.com> boring babbled:
>But a proper C++-ish wrapper would look like this:
>
>template<typename Fn>
>void xfork( Fn &&&fn )
                ^^^

What?

>	if constexpr( same_as<invoke_result_t<Fn>, int> )

What?

Have you got something against simply passing std::function ?

[toc] | [prev] | [next] | [standalone]


#120968

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-11-21 17:59 +0100
Message-ID<vhnori$nk9a$1@raubtier-asyl.eternal-september.org>
In reply to#120966
Am 21.11.2024 um 17:11 schrieb Muttley@DastartdlyHQ.org:
> On Thu, 21 Nov 2024 15:27:59 +0100
> Bonita Montero <Bonita.Montero@gmail.com> boring babbled:
>> But a proper C++-ish wrapper would look like this:
>>
>> template<typename Fn>
>> void xfork( Fn &&&fn )
>                  ^^^
> 
> What?

Just a typo.

>> 	if constexpr( same_as<invoke_result_t<Fn>, int> )

> What?
> Have you got something against simply passing std::function ?

A std::function isn't necessary here since I don't need any type erasure
with that.

[toc] | [prev] | [next] | [standalone]


#120972

FromMuttley@DastartdlyHQ.org
Date2024-11-22 09:54 +0000
Message-ID<vhpkd3$14hms$1@dont-email.me>
In reply to#120968
On Thu, 21 Nov 2024 17:59:21 +0100
Bonita Montero <Bonita.Montero@gmail.com> boring babbled:
>Am 21.11.2024 um 17:11 schrieb Muttley@DastartdlyHQ.org:
>> On Thu, 21 Nov 2024 15:27:59 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> boring babbled:
>>> But a proper C++-ish wrapper would look like this:
>>>
>>> template<typename Fn>
>>> void xfork( Fn &&&fn )
>>                  ^^^
>> 
>> What?
>
>Just a typo.
>
>>> 	if constexpr( same_as<invoke_result_t<Fn>, int> )
>
>> What?
>> Have you got something against simply passing std::function ?
>
>A std::function isn't necessary here since I don't need any type erasure
>with that.

Gibberish.

[toc] | [prev] | [next] | [standalone]


#120967

Fromwij <wyniijj5@gmail.com>
Date2024-11-22 00:32 +0800
Message-ID<6d976f878d1ad19f2a7039b1f21678c9be66d358.camel@gmail.com>
In reply to#120963
On Thu, 2024-11-21 at 15:27 +0100, Bonita Montero wrote:
> But a proper C++-ish wrapper would look like this:
> 
> template<typename Fn>
> void xfork( Fn &&&fn )
> {
> 	int pid = fork();
> 	if( pid == -1 )
> 		throw system_error( errno, system_category(), "fork failed" );
> 	if( pid )
> 		return;
> 	if constexpr( same_as<invoke_result_t<Fn>, int> )
> 		exit( fn() );
> 	else
> 	{
> 		fn();
> 		exit( 0 );
> 	}
> }
> 
> There's no need for a process wrapper class if you fork only.

That's what I thought. But, as I said, "C++ is a C wrapper language".

int ftask(int) {
 // asdf
 return 0;
};

ForkProcess fproc(ftask,1);   // fork a process to run ftask(1)

----
Particularily, I just found shm_open(3), sem_open(3) on Linux seem matured.
Such simple wrapper (like ForkProcess) can be very 'powerful'. E.g. ALL
running programs in the OS are forked processes.
The following example is just a basic usage for 'advanced IPC':

------- t_mm.cpp
#include <Wy.stdio.h>
#include <Wy.unistd.h>
#include <CSCall/mman.h>

using namespace Wy;

int main(int argc, const char* argv[])
try {
 Errno r;
 RegFile regf1(__FILE__,O_RDWR);
 off_t flen;

 if((r=regf1.get_file_size(flen))!=Ok) {
  WY_THROW(r);
 }

 // Ex1: Copy __FILE__ to "file.tmp", using mmap(2)
 //
 MemMap mmap1(NULL,flen,PROT_READ|PROT_WRITE,MAP_PRIVATE,regf1.fh().fd(),0);

 cout << StrSeg(static_cast<const char*>(mmap1.addr()), flen);

 RegFile regf2("file.tmp", O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
 if((r=regf2.resize(flen))!=Ok) {
   WY_THROW(r);
 }
 MemMap mmap2(NULL,flen,PROT_READ|PROT_WRITE,MAP_SHARED,regf2.fh().fd(),0);

 ::memcpy(mmap2.addr(),mmap1.addr(),flen);

 if((r=Wy::msync(mmap2.addr(),flen,MS_SYNC))!=Ok) {
   WY_THROW(r);
 }

 // Ex2: Shared memory object example
 //
 const char* shm_name="/shmf";
 ShmFile shmf(shm_name, O_CREAT|O_EXCL|O_RDWR, 0600);
 MemMap mmap3(NULL,flen, PROT_READ|PROT_WRITE, MAP_SHARED, regf1.fh().fd(), 0);

 // ...Do something in the shared memory

 if((r=Wy::shm_unlink(shm_name))!=Ok) {
   WY_THROW(r);
 }

 cout << "OK" WY_ENDL;
 return 0;
}
catch(const Errno& e) {
 cerr << wrd(e) << WY_ENDL;
 return e.c_errno();
}
catch(...) {
 cerr << "main() caught(...)" WY_ENDL;
 throw;
};

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web