- Subject: Re: [slang-users] fork with shared memory
- From: "John E. Davis" <davis@xxxxxxxxxxxxx>
- Date: Thu, 10 Nov 2011 13:45:52 -0500
Thomas Dauser <thomas.dauser@xxxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
[...]
> Now my question: Is there any possibility to do this with shared memory,
> such that the child process changes the value of the "test"-variable?
> I found things like shmget() and vfork() for other programming
> languages, but I did not find any slang-function, which can solve this
> issue.
As far as I know, vfork is mainly used to call one of the exec
functions; it is unclear to me from your example if that is what you
want.
As you discovered, slang has no shared memory module. I have not
written one because I never saw the utility of such a generic module
for a dynamically-typed interpreter where the memory attached to a
variable changes over time.
Rather I think that it is better to use a message-based system to
communicate between interpreter processes, e.g., via a socket. Even if
slang were to have a shared memory module, there would still be the
need to synchronize read/writes to a memory segment through the use of
semaphores, etc. That is, the processes would still need some form of
communication to properly share the memory.
Below is a simple example slsh script that creates a process to ROT13
a character string and send the encoded string back to the parent
process. Although it does not define any explicit message interface,
it should give you an idea of what is involved at the lowest level. A
much higher level interface exists in the isis
<http://space.mit.edu/cxc/isis/> source code in a file called
fork_socket.sl. This file is not isis-specific and should run in any
slang interpreter. It is used to perform parallel processing on a
multicore CPU.
I hope this helps.
Thanks, --John
------------------------------------------------------------------------
require ("fork");
require ("socket");
private define create_process_info (s, pid)
{
variable p = struct
{
fp = fdopen (s, "w+"),
pid = pid,
s = s,
};
% turn off buffering of stdio streams for robust signal handling
() = setvbuf (p.fp, _IONBF, 0);
return p;
}
private define create_child (taskfunc, arglist)
{
variable s1, s2, pid, p;
(s1, s2) = socketpair (PF_UNIX, SOCK_STREAM, 0);
pid = fork ();
if (pid > 0)
{
() = close (s2);
return create_process_info (s1, pid);
}
% child code
signal (SIGINT, SIG_DFL);
signal (SIGCHLD, SIG_DFL);
() = setpgid (0, 0);
() = close (s1);
p = create_process_info (s2, pid);
_exit ((@taskfunc)(p, __push_list (arglist)));
}
private define do_rot13 (p)
{
variable line;
while (-1 != fgets (&line, p.fp))
{
line = strtrans (line, "a-mn-zA-MN-Z", "n-za-mN-ZA-M");
() = fputs (line, p.fp);
}
() = fclose (p.fp);
return 0;
}
private variable Sigchld_Received = 0;
private define sigchld_handler (sig)
{
Sigchld_Received++;
}
define slsh_main ()
{
signal (SIGCHLD, &sigchld_handler);
variable p = create_child (&do_rot13, {});
variable rline = slsh_readline_new ("demo");
while (Sigchld_Received == 0)
{
variable line;
try
{
line = slsh_readline (rline, "demo> ");
}
catch UserBreakError: line = NULL;
if (line == NULL)
break;
if ((-1 == fprintf (p.fp, "---> %s\n", line))
|| (-1 == fgets (&line, p.fp)))
break;
() = fprintf (stdout, "%s", line);
}
() = kill (p.pid, SIGTERM);
() = waitpid (p.pid, 0);
}
[2011 date index]
[2011 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]