#python #c #fork
#python #c #форк
Вопрос:
Я пытаюсь связать свой код c с моим кодом python. Я создаю канал имен в своем коде на c, отправляю его на python, и python распечатывает его. Я хочу сделать то же самое, когда я создаю именованный канал в python, а c считывает его, однако моя программа, похоже, останавливается (я хочу сделать оба сразу), поэтому я использую процессы.
Мой c-код:
int main(void) {
int pid;
FILE * fp;
char *calledPython="./a.py";
char *pythonArgs[]={"python",calledPython,"a","b","c",NULL};
FILE * fp2;
char str[40];
pid = fork();
if(pid == 0) {
mkfifo("./test",0666);
fp = fopen("./test","w");
fprintf(fp,"Hellon");
fprintf(fp,"Worldn");
}
else {
execvp("python",pythonArgs);
// if we get here it misfired
perror("Python execution");
kill(pid,SIGKILL);
}
fp2 = fopen("./test2","r");
if(fp2 == NULL) {
printf("NUlln");
}
else {
fscanf(fp2, "%s", str);
printf("received from test2 %sn", str);
}
fclose(fp);
return 0;
}
Мой код на python:
#!/usr/bin/python
import os, sys
with open("./test") as fp:
for line in fp:
print line
path = "./test2"
os.mkfifo(path)
fifo = open(path,"w")
fifo.write("Message from the sendern")
fifo.close()
Где ./test — это начальный именованный канал, в который python считывает, а ./test2 — это второй именованный канал, в который c отправляется для чтения.
Однако моя программа зависает, как только я записываю в свой второй канал на python:
path = "./test2"
os.mkfifo(path)
fifo = open(path,"w")
fifo.write("Message from the sendern")
fifo.close()
Вывод, который я получаю от терминала:
NUll
Hello
World
если я запускаю ее снова, я просто получаю пустую строку (вообще ничего не печатается).
Я попытался открыть второй именованный канал в родительском процессе, который, похоже, не сильно изменился. Я не уверен, где я ошибся, есть идеи?
Комментарии:
1. Похоже, что он полон условий гонки.
Ответ №1:
В настоящее время у меня нет под рукой unix-блока для тестирования. Но вероятная проблема заключается в том, что вы не закрываете fifo в родительском процессе.
Всякий раз, когда у вас есть подобный цикл for line in file
, этот цикл будет продолжаться до тех пор, пока файл не закончится. В отличие от обычного файла, файл fifo не «завершается», пока процесс на стороне записи не закроет файл fifo. Если вы не закроете fifo, процесс чтения заблокируется при вызове read и не сможет развиваться.
В вашем коде могут быть другие проблемы, которые я упускаю.
Некоторые другие примечания:
-
Вы должны выполнить mkfifo перед выполнением execvp, в настоящее время вы выполняете их параллельно и надеетесь, что mkfifo завершится до того, как ваша программа python попытается открыть файл. Вероятно, но не наверняка.
-
Во втором fifo есть еще одно условие гонки, которое, я думаю, вряд ли будет работать так, как задумано.
-
Вы никогда не удаляете именованный канал, в следующий раз он попытается создать уже существующий файл, который не будет работать.
-
SIGKILL редко является правильным сигналом для использования. Я рекомендую вам ознакомиться с разницей между SIGKILL, SIGTERM и т. Д.
-
Системные вызовы, такие как mkfifo, могут завершиться неудачно, и рекомендуется проверять возвращаемое значение на наличие ошибок.