Re: Wiki Article: Asynchronous Events and Family IPC
By the way, the picolisp twitter account is great !!! :-) JC > On May 8, 2022, at 14:08, Alexander Burger wrote: > > Hi all, > > a new Wiki article about internal background processing, asynchronous events > and > family IPC in PicoLisp: > > https://picolisp.com/wiki/?background > > I think this was not yet documented anywhere. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe -- Jean-Christophe Helary @brandelune https://mac4translators.blogspot.com https://sr.ht/~brandelune/omegat-as-a-book/ -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Wiki Article: Asynchronous Events and Family IPC
Hi all, a new Wiki article about internal background processing, asynchronous events and family IPC in PicoLisp: https://picolisp.com/wiki/?background I think this was not yet documented anywhere. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: IPC
Hi Alex, The fifo is there to defer requests for chopsticks when the philosopher is hungry or eating. Do you have any other mechanism in mind? As the tell - hear mechanism is a pipe, it behaves like a fifo. So I would expect that this would suffice. Not due to the logic of the algorithm, e.g. when the philosopher is hungry, he must hand over dirty forks immediately but not clean forks. He must remember that he was asked for it and hand it over when he is finished. I should explain that the internal tell - hear mechanism maintains dynamic buffers for each parent/child connection, to avoid blocking if a child should not fetch (hear) its data fast enough. This way, the standard limitation of the PIPE_BUF size is avoided. That's good to know. Thank you, Tomas -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: IPC
Hi Alex, There is no other place where the internal event loop (the C-function waitFd()) is called. I see. I'm wondering whether the 'fifo' is really necessary? The fifo is there to defer requests for chopsticks when the philosopher is hungry or eating. Do you have any other mechanism in mind? Cheers, Tomas -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: IPC
Hi all, the Chandy / Misra solution to Dining Philosophers Problem in picolisp seems to be working now so the code is now at http://logand.com/sw/phil.l for anybody interested. The problem with the previous code was that once the hungry philosopher handed over his dirty fork, he had to ask to get it back. This was the message I thought was getting lost but it was not generated in the first place. Thanks Alex for your suggestions. Cheers, Tomas -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: IPC
Hi Alex, as in 'open'. Therefore, I would rather reduce the functionality of 'hear', so that from now on it only accepts a file descriptor (and no longer a symbolic argument). I'll write it into the ReleaseNotes. I see, thank you. You tried to use 'rpc' to send messages to the other philosophers. While this is basically a correct idea, 'rpc' is not suitable in the current situation. It sends the message via standard output, and is intended to be used in a 'pipe' call. What is the functional difference between 'rpc' and 'pr' and why the specific constraint on 'rpc' being suitable only for stdout? With 'rpc' I get: : (hear (pipe (do 3 (wait 2000) (rpc 'println ''Ok - 3 : Ok Ok Ok and with 'pr' I get the same thing: : (hear (pipe (do 3 (wait 2000) (pr '(println 'Ok)) (flush - 3 : Ok Ok Ok If you look in the reference for 'hear', it says hear is usually only called explicitly by a top level parent process. The reason is that upon a 'fork', the 'hear' channel is automatically set up in the child process to be used by the built-in IPC routines. I see, where can I find this automatic channel, is it a named pipe? If not, what channel is used for communication? As a consequence, if you re-open that channel with 'hear', the child is effectively cut off from its parent and could, for example, not synchronize on DB operations. I noticed that 'tell' did not work for me when I opened the fifos, so this is why:-) So the recommended and natural way is to use 'tell'. In combination with 'pid', it can also send messages selectively to other processes. Using 'tell' I cannot send a message to the parent process though. I would like to have the philosophers talking to a monitor process which cannot be the parent but must be another child for 'tell' to work. Is that correct? How are children supposed to communicate with the parent process? As an example, I modified your phil.l (I hope I understood it). Each philosopher (process) keeps the PIDs of his neighbors in the global variables '*LeftNeighbor' and '*RightNeighbor', and the state of the forks in '*LeftFork' and '*RightFork'. In the beginning, he waits until he received the PIDs from the parent process. That's interesting, thank you. 'tell' seems to be asynchronous. If I want to query the philosopher processes about their state, I cannot use something like: (de philState () (list *Pid *State *LeftFork *RightFork) ) .. and in *Monitor process call... (let S (tell 'pid P 'philState) (println S) because 'tell' does not return the result of calling 'philState'. Is there a standard/easy way of achieving this? Thank you, Tomas -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: IPC
Hi Tomas, for phil.l, I'd suggest another change (besides the call to 'hear'). You tried to use 'rpc' to send messages to the other philosophers. While this is basically a correct idea, 'rpc' is not suitable in the current situation. It sends the message via standard output, and is intended to be used in a 'pipe' call. Instead, you could directly call 'pr', so that (rpc 'obtain I) becomes (pr (list 'obtain I)) and (rpc 'give I) becomes (pr (list 'give I)) Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
IPC
Hi Alex, I am struggling to understand picolisp IPC functions (hear, tell, rpc, sync...). I have attached code for the Dining Philosophers problem which gets stuck after calling 'hear' in the philosopher (child) process. The idea is that each philosopher is a process which opens a fifo and all philosophers talk to their neighbours via those fifos. 'hear' in the following snippet seems to block the whole process: ... (log 'before) (hear (mailbox I)) (log 'after) ... outputs $ ~/picolisp/p phil.l 0 -1 0 before 1 -1 0 before 2 -1 0 before 3 -1 0 before 4 -1 0 before : ..only and does nothing afterwards. I would expect 'hear' to install some kind of event handler which would evaluate incoming messages and then carry on immediately with the next (log 'after) line. Is my understanding correct? I though that 'hear' was working in the background so why the code blocks? Thank you, Tomas # ~/picolisp/p phil.l # http://en.wikipedia.org/wiki/Dining_philosophers_problem # Chandy / Misra solution # philosophers: N = total, I = current, P = other # forks: L = left, R = right; lt0 ~ dirty, =0 none, gt0 ~ clean (de log @ (pass println I L R) (flush) ) (de idle () (wait (rand 1000 3000)) ) (de left () (% (+ N (- I 1)) N) ) (de right () (% (+ I 1) N) ) (de mailbox (P) (pack phil P) ) (de obtain (P) (log 'obtain P) (when (= P (left)) (if (=0 L) (setq L 1) (quit Already have the left fork) ) ) (when (= P (right)) (if (=0 R) (setq R 1) (quit Already have the right fork) ) ) ) (de give (P) (log 'give P) (when (and (= P (left)) (lt0 L)) (out (mailbox P) (rpc 'obtain I) ) (setq L 0) ) (when (and (= P (right)) (lt0 R)) (out (mailbox P) (rpc 'obtain I) ) (setq R 0) ) ) (de grab () (while (or (=0 L) (=0 R)) (when (lt0 L) (setq L 1) ) (when (lt0 R) (setq R 1) ) (when (=0 L) (out (mailbox (left)) (rpc 'give I) ) ) (when (=0 R) (out (mailbox (right)) (rpc 'give I) ) ) (wait 500) ) ) (de phil (I N L R) (unless (info (mailbox I)) (call 'mkfifo (mailbox I)) ) (log 'before) (hear (mailbox I)) (log 'after) (loop (log 'thinking) (idle) # think (log 'hungry) (grab) (log 'eating) (idle) # eat (setq L -1 R -1) ) ) # dirty (de main (N) (push '*Bye '(mapc 'kill *C)) (for (I 0 ( I N) (inc I)) (if (fork) (push '*C @) (phil I N -1 0) ) ) ) (main 5)