I'm on Windows 10. I have a program written in c, that simply prints to the stdout and sleeps between prints, emulating some real work. I try to call this program from python (3.7.7) using asyncio and capture the prints to the program's stdout. I would expect that the prints are captured "real-time", however it seems that they are captured only at the end, when the c program has finished.
If I try to do the same thing with windows shell commands, it works, the prints to the stdout are captured as they are produced.
What am I missing? I would think that the stdout being forwarded to an asyncio subprocess pipe can be properly awaited on.
/* cproc.c, compiled to cproc.exe */
#include <stdio.h>
#include <windows.h>
int main() {
int i;
for (i=0; i<3; i++) {
printf("%i\n", i);
Sleep(500);
}
return 0;
}
import asyncio
import time
async def doit():
# this does not work:
command = ["cproc.exe"]
# this works:
command = [
r"c:\Windows\System32\cmd.exe",
"/c",
"echo 1 & sleep 0.5 & echo 2 & sleep 0.5 & echo 3"
]
proc = await asyncio.create_subprocess_exec(
*command,
stdout=asyncio.subprocess.PIPE
)
while True:
data = await proc.stdout.readline()
if data == b'':
break
line = data.decode('utf-8').rstrip()
print(f"line @ {time.time()}: {line}")
await proc.wait()
if __name__ == '__main__':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
loop.run_until_complete(doit())
Outputs with calling cproc.exe, it can be seen that the lines were captured at the same moment:
line @ 1593940000.8466766: 0
line @ 1593940000.8466766: 1
line @ 1593940000.8466766: 2
Outputs with calling the windows shell commands, with proper timestamps:
line @ 1593939899.394881: 0
line @ 1593939900.402128: 1
line @ 1593939900.9687984: 2