- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的程序及其两个子进程都以有序的方式从标准输入读取输入。我发现的问题是:
鉴于此输入:
32
51453a
140
父进程读到32,也就是说第一个子进程需要再读2个数。父进程然后通过管道发送 1 个字节,向第一个进程发出信号,它需要读取两个数字。当子进程接收到信号并开始读取这些数字时,子进程读取的不是 51453a 和 140,而是 32 51453a。
我一直在努力理解为什么会发生这种情况,如何解决或更好,如何避免这种情况。
我在 Mac OSX 上运行
编辑:此问题仅在从文件重定向输入(运行 ./polygon < in.txt)时发生。当直接从控制台运行时,它不会发生。还添加了更多代码以提供更好的画面。
void runWriterProcess(char *outFile, int writerFd[2]) {
close(writerFd[1]);
close(STDIN_FILENO);
dup(writerFd[0]);
close(writerFd[0]);
char *const params[] = {"./writer", outFile, NULL};
execv("./writer", params);
}
void reader32(int INSIG, int OUTPUT) {
long unsigned polygonParts[2];
char runSignal[2], polygonBuffer[17];
int64 nextPolygon;
while(read(INSIG, runSignal, 1) > 0) {
scanf("%lx", &polygonParts[0]);
scanf("%lx", &polygonParts[1]);
nextPolygon = polygonParts[1];
nextPolygon = nextPolygon << 32;
nextPolygon += polygonParts[0];
sprintf(polygonBuffer, "%16llx", nextPolygon);
write(OUTPUT, polygonBuffer, (int)strlen(polygonBuffer));
}
finishError("reader32\0");
exit(EXIT_SUCCESS);
}
void reader64(int INSIG, int OUTPUT) {
char runSignal[2], polygonBuffer[17];
int64 nextPolygon;
while(read(INSIG, runSignal, 1) > 0) {
scanf("%16llx", &nextPolygon);
sprintf(polygonBuffer, "%16llx", nextPolygon);
write(OUTPUT, polygonBuffer, 16);
}
finishError("reader64\0");
exit(EXIT_SUCCESS);
}
void runMainLoop(int reader32, int reader64, int readPipe) {
long unsigned dummy[2];
int64 bigDummy, nextPolygon;
char polygonBuffer[17];
int readerToRun;
for(;;) {
scanf("%d", &readerToRun);
if (readerToRun == 32) {
write(reader32, "1", 1);
} else {
write(reader64, "1", 1);
}
read(readPipe, polygonBuffer, 16);
sscanf(polygonBuffer, "%16llx", &nextPolygon);
if(runOnPolygon(nextPolygon)) break;
}
write(reader64, "0\n", 2);
}
void createReaders(pid_t *reader32pid, pid_t *reader64pid) {
int fd32[2], fd64[2], fdBoth[2], readerToRun;
long unsigned polygonParts[2];
int64 nextPolygon, dummy;
char runSignal[2], polygonBuffer[17];
polygonBuffer[16] = '\0';
pipe(fd32);
pipe(fd64);
pipe(fdBoth);
if ((*reader32pid = fork()) == 0) {
close(fd32[1]);
close(fd64[0]);
close(fd64[1]);
close(fdBoth[0]);
reader32(fd32[0], fdBoth[1]);
}
if ((*reader64pid = fork()) == 0) {
close(fd32[0]);
close(fd32[1]);
close(fd64[1]);
close(fdBoth[0]);
reader64(fd64[0], fdBoth[1]);
}
close(fd32[0]);
close(fd64[0]);
close(fdBoth[1]);
runMainLoop(fd32[1], fd64[1], fdBoth[0]);
close(fd32[1]);
close(fd64[1]);
wait(NULL);
wait(NULL);
finishError("main_process\0");
}
void finishError(char processName[13]) {
char output[50];
sprintf(output, "%s pid=%d is going to exit\n", processName, getpid());
write(STDERR_FILENO, output, strlen(output) + 1);
}
int main(int argc, const char *argv[])
{
polygonList.head = NULL;
polygonList.tail = NULL;
pid_t writerPid, reader32pid, reader64pid;
int writerFd[2];
char outFile[11];
scanf("%s", outFile);
pipe(writerFd);
if (fork() == 0) {
runWriterProcess(outFile, writerFd);
} else {
close(STDOUT_FILENO);
dup(writerFd[1]);
close(writerFd[0]);
close(writerFd[1]);
createReaders(&reader32pid, &reader64pid);
}
freeList();
return 0;
}
最佳答案
这叫做缓冲。当您fork
时,子进程几乎是父进程的完整副本,包括输入缓冲区等内容。
最好的解决方案 (IMO) 是不从 child 的标准输入中读取。而是让父进程完成所有输入,然后通过管道将其发送给子进程。
关于c - scanf from child 扫描任何 parent 已经扫描过的东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47927400/
一段时间以来,我一直在做这个反复出现的噩梦(阅读 - 我的应用程序中的错误)。出于某种原因,某个计时器在我停止后继续发送“Elapsed”事件,即使 在事件本身 计时器“承认”已被禁用!检查一下: /
为了找到 2 个 git 分支的共同祖先,需要做的是: git merge-base branch another_branch 好的。但是……如果两个分支都已经 merge 了怎么办?当我在这种情况
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 1年前关闭。 Improve this
我想要一个相机 View ,可以将图像捕获到本地文件或让用户从本地照片库中选择图像。我想也许有人为此编写了很好的库/代码。也许我可以利用它。已经有好的了吗?谢谢。我只是避免重新发明轮子:) 最佳答案
我从 master 分支创建了一个功能分支。之后有来自功能分支的提交 [F1]。 [F1] -- Feature Branch / [M1]-[M2
我喜欢使用 .NET 进行编程,尤其是 C# 3.0、.NET 3.5 和 WPF。但我特别喜欢的是 Mono .NET 确实与平台无关。 现在我听说了 Mono 中的 Olive 项目。我找不到某种
介绍和搜索 所以我认为我犯了一个严重的错误,我很担心。我已经分析了独立负责人的论坛,我已经接近找到答案,但场景太具体,不适用于我所在的位置。如果您找到可以回答我的问题的特定主题,请链接我。 例如:Ho
我有一个类似于下图的提交图。标记为 * 的提交表示大量提交。 A* | B--------- | | C* D* master 和 cor
我喜欢使用 .NET 进行编程,尤其是 C# 3.0、.NET 3.5 和 WPF。但我特别喜欢的是 Mono .NET 确实与平台无关。 现在我听说了 Mono 中的 Olive 项目。我找不到某种
我们最近接手了一个 .NET 项目,在查看 db 后,我们在某些列中有以下内容: 1)某些列具有诸如" & etc etc 2) 有些有 标签和其他非 html 编码的标签 这些数据
你好,当我导航到应用程序中的另一个页面时出现此错误 我不知道为什么这个错误出现 #0 _AsyncCompleter.complete (dart:async/future_impl.da
我使用以下 C 算法计算数据的 CRC32: #define CRC32_POLYNOM_REVERSED 0xEDB88320 uint32 calcCrc32(uint8* buffer, u
我试图在我的一个测试中断言模型中的字段没有改变。我知道从哲学上这是不正确的,但由于我控制了我需要知道的所有变量,所以我只想检查我的数据库条目是否没有改变。 我愿意接受一个解决方案,该解决方案可以将其转
我是 GitHub 的新手。并通过 Eclipse 使用它我们是两个人在开发一个应用程序。当我在 Git shell 中检查 git status 时,我得到以下状态。 On branch maste
简单代码: std::ifstream file("file.txt"); std::string line; while(getline(file,line)) ; //exhaust file
是的,我又找不到这个 Gradle DSL 方法:'compile()' 问题。 我检查了我有: buildscript { repositories { jcenter()
HTML: articles CSS: #main_menu { float: left; padding-top: 10px; vertical-align: m
我是一名优秀的程序员,十分优秀!