Thanks for your comment re blocking.  

I removed pipes from the Python and C programs to see if it blocks without 
them, and it does.  It looks now like the problem is not pipes.  I use fork() 
and execv() in C to run Python in a child process, but the Python process 
blocks because fork() does not create a new thread, so the Python global 
interpreter lock (GIL) prevents the C program from running once Python starts.  
So the solution appears to be run Python in a separate thread, which I can do 
with pthread create.  See "Thread State and the Global Interpreter Lock" 
https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
 and the sections below that "Non-Python created threads" and "Cautions about 
fork()." 

I'm working on that today and I hope all goes well :) 



Nov 30, 2021, 11:42 by ba...@barrys-emacs.org:

>
>
>
>> On 29 Nov 2021, at 22:31, Jen Kris <>> jenk...@tutanota.com>> > wrote:
>>
>> Thanks to you and Cameron for your replies.  The C side has an epoll_ctl 
>> set, but no event loop to handle it yet.  I'm putting that in now with a 
>> pipe write in Python-- as Cameron pointed out that is the likely source of 
>> blocking on C.  The pipes are opened as rdwr in Python because that's 
>> nonblocking by default.  The child will become more complex, but not in a 
>> way that affects polling.  And thanks for the tip about the c-string 
>> termination. 
>>
>>
>
> flags is a bit mask. You say its BLOCKing by not setting os.O_NONBLOCK.
> You should not use O_RDWR when you only need O_RDONLY access or only O_WRONLY 
> access.
>
> You may find
>
> man 2 open
>
> useful to understand in detail what is behind os.open().
>
> Barry
>
>
>
>
>>
>>
>> Nov 29, 2021, 14:12 by >> ba...@barrys-emacs.org>> :
>>
>>>
>>>
>>>> On 29 Nov 2021, at 20:36, Jen Kris via Python-list <>>>> 
>>>> python-list@python.org>>>> > wrote:
>>>>
>>>> I have a C program that forks to create a child process and uses execv to 
>>>> call a Python program.  The Python program communicates with the parent 
>>>> process (in C) through a FIFO pipe monitored with epoll(). 
>>>>
>>>> The Python child process is in a while True loop, which is intended to 
>>>> keep it running while the parent process proceeds, and perform functions 
>>>> for the C program only at intervals when the parent sends data to the 
>>>> child -- similar to a daemon process. 
>>>>
>>>> The C process writes to its end of the pipe and the child process reads 
>>>> it, but then the child process continues to loop, thereby blocking the 
>>>> parent. 
>>>>
>>>> This is the Python code:
>>>>
>>>> #!/usr/bin/python3
>>>> import os
>>>> import select
>>>>
>>>> #Open the named pipes
>>>> pr = os.open('/tmp/Pipe_01', os.O_RDWR)
>>>>
>>> Why open rdwr if you are only going to read the pipe?
>>>
>>>> pw = os.open('/tmp/Pipe_02', os.O_RDWR)
>>>>
>>> Only need to open for write.
>>>
>>>>
>>>> ep = select.epoll(-1)
>>>> ep.register(pr, select.EPOLLIN)
>>>>
>>>
>>> Is the only thing that the child does this:
>>> 1. Read message from pr
>>> 2. Process message
>>> 3. Write result to pw.
>>> 4. Loop from 1
>>>
>>> If so as Cameron said you do not need to worry about the poll.
>>> Do you plan for the child to become more complex?
>>>
>>>>
>>>> while True:
>>>>
>>>> events = ep.poll(timeout=2.5, maxevents=-1)
>>>> #events = ep.poll(timeout=None, maxevents=-1)
>>>>
>>>> print("child is looping")
>>>>
>>>> for fileno, event in events:
>>>> print("Python fileno")
>>>> print(fileno)
>>>> print("Python event")
>>>> print(event)
>>>> v = os.read(pr,64)
>>>> print("Pipe value")
>>>> print(v)
>>>>
>>>> The child process correctly receives the signal from ep.poll and correctly 
>>>> reads the data in the pipe, but then it continues looping.  For example, 
>>>> when I put in a timeout:
>>>>
>>>> child is looping
>>>> Python fileno
>>>> 4
>>>> Python event
>>>> 1
>>>> Pipe value
>>>> b'10\x00'
>>>>
>>> The C code does not need to write a 0 bytes at the end.
>>> I assume the 0 is from the end of a C string.
>>> UDS messages have a length.
>>> In the C just write 2 byes in the case.
>>>
>>> Barry
>>>
>>>> child is looping
>>>> child is looping
>>>>
>>>> That suggests that a while True loop is not the right thing to do in this 
>>>> case.  My question is, what type of process loop is best for this 
>>>> situation?  The multiprocessing, asyncio and subprocess libraries are very 
>>>> extensive, and it would help if someone could suggest the best alternative 
>>>> for what I am doing here. 
>>>>
>>>> Thanks very much for any ideas. 
>>>>
>>>>
>>>> -- 
>>>> https://mail.python.org/mailman/listinfo/python-list
>>>>
>>
>>

-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to