为什么分叉我的进程会导致文件被无限读取

2024-04-06

我已经将整个程序简化为一个简短的主程序来复制该问题,所以请原谅我它没有任何意义。

input.txt 是一个文本文件,其中包含几行文本。这个简化的程序应该打印这些行。但是,如果调用 fork,程序就会进入无限循环,一遍又一遍地打印文件的内容。

据我了解 fork,我在这段代码中使用它的方式本质上是无操作。它分叉,父进程在继续之前等待子进程,子进程立即被杀死。

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

enum { MAX = 100 };

int main(){
    freopen("input.txt", "r", stdin);
    char s[MAX];

    int i = 0;
    char* ret = fgets(s, MAX, stdin);
    while (ret != NULL) {
        //Commenting out this region fixes the issue
        int status;
        pid_t pid = fork();
        if (pid == 0) {
            exit(0);
        } else {
            waitpid(pid, &status, 0);
        }
        //End region
        printf("%s", s);
        ret = fgets(s, MAX, stdin);
    }
}

编辑:进一步的调查只会让我的问题变得更奇怪。如果文件包含

Edit2:如果文件包含数字3行数字,它将无限循环,但如果它包含3行单词,则不会。


我很惊讶有一个问题,但它在 Linux 上似乎确实是一个问题(我在 Mac 上的 VMWare Fusion VM 中运行的 Ubuntu 16.04 LTS 上进行了测试),但在运行 macOS 10.13 的 Mac 上这不是问题。 4 (High Sierra),我也不认为这在其他 Unix 变体上会成为问题。

正如我在一篇文章中指出的comment https://stackoverflow.com/questions/50110992/why-does-forking-my-process-cause-the-file-to-be-read-infinitely#comment87240933_50111085:

每个流后面都有一个打开的文件描述和一个打开的文件描述符。当进程分叉时,子进程拥有自己的一组打开文件描述符(和文件流),但子进程中的每个文件描述符与父进程共享打开文件描述。IF(这是一个很大的“如果”)子进程首先关闭文件描述符所做的相当于lseek(fd, 0, SEEK_SET),那么这也会定位父进程的文件描述符,这可能会导致无限循环。然而,我从未听说过有哪个图书馆会这样做;没有理由这样做。

参见 POSIXopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html and fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html有关打开文件描述符和打开文件描述的更多信息。

打开的文件描述符是进程私有的;打开文件描述由初始“打开文件”操作创建的文件描述符的所有副本共享。打开文件描述的关键属性之一是当前查找位置。这意味着子进程可以更改父进程的当前查找位置 - 因为它位于共享的打开文件描述中。

neof97.c

我使用了以下代码 - 原始代码的轻微改编版本,可以使用严格的编译选项进行干净的编译:

#include "posixver.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

enum { MAX = 100 };

int main(void)
{
    if (freopen("input.txt", "r", stdin) == 0)
        return 1;
    char s[MAX];
    for (int i = 0; i < 30 && fgets(s, MAX, stdin) != NULL; i++)
    {
        // Commenting out this region fixes the issue
        int status;
        pid_t pid = fork();
        if (pid == 0)
        {
            exit(0);
        }
        else
        {
            waitpid(pid, &status, 0);
        }
        // End region
        printf("%s", s);
    }
    return 0;
}

其中一项修改将循环(子循环)数量限制为 30。 我使用的数据文件有 4 行,每行 20 个随机字母加一个换行符(总共 84 个字节):

ywYaGKiRtAwzaBbuzvNb
eRsjPoBaIdxZZtJWfSty
uGnxGhSluywhlAEBIXNP
plRXLszVvPgZhAdTLlYe

我在下面运行了命令strace在Ubuntu上:

$ strace -ff -o st-out -- neof97
ywYaGKiRtAwzaBbuzvNb
eRsjPoBaIdxZZtJWfSty
uGnxGhSluywhlAEBIXNP
plRXLszVvPgZhAdTLlYe
…
uGnxGhSluywhlAEBIXNP
plRXLszVvPgZhAdTLlYe
ywYaGKiRtAwzaBbuzvNb
eRsjPoBaIdxZZtJWfSty
$

有 31 个文件,其名称格式为st-out.808##其中哈希值是两位数。主进程文件相当大;其他尺寸较小,尺寸为 66、110、111 或 137 之一:

$ cat st-out.80833
lseek(0, -63, SEEK_CUR)                 = 21
exit_group(0)                           = ?
+++ exited with 0 +++
$ cat st-out.80834
lseek(0, -42, SEEK_CUR)                 = -1 EINVAL (Invalid argument)
exit_group(0)                           = ?
+++ exited with 0 +++
$ cat st-out.80835
lseek(0, -21, SEEK_CUR)                 = 0
exit_group(0)                           = ?
+++ exited with 0 +++
$ cat st-out.80836
exit_group(0)                           = ?
+++ exited with 0 +++
$

碰巧的是,前 4 个孩子每人都表现出四种行为中的一种,而接下来的每组 4 个孩子都表现出相同的模式。

这表明四分之三的孩子确实在做lseek()退出之前在标准输入上。显然,我现在已经看到图书馆这样做了。我不知道为什么它被认为是一个好主意,但从经验来看,这就是正在发生的事情。

neof67.c

此版本的代码使用单独的文件流(和文件描述符)和fopen()代替freopen()也遇到了问题。

#include "posixver.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

enum { MAX = 100 };

int main(void)
{
    FILE *fp = fopen("input.txt", "r");
    if (fp == 0)
        return 1;
    char s[MAX];
    for (int i = 0; i < 30 && fgets(s, MAX, fp) != NULL; i++)
    {
        // Commenting out this region fixes the issue
        int status;
        pid_t pid = fork();
        if (pid == 0)
        {
            exit(0);
        }
        else
        {
            waitpid(pid, &status, 0);
        }
        // End region
        printf("%s", s);
    }
    return 0;
}

这也表现出相同的行为,除了发生查找的文件描述符是3代替0。所以,我的两个假设被证明是错误的——它与freopen() and stdin;第二个测试代码显示两者都不正确。

初步诊断

IMO,这是一个错误。您不应该遇到这个问题。 这很可能是 Linux (GNU C) 库而不是内核中的错误。这是由lseek()在子进程中。目前尚不清楚(因为我没有去查看源代码)该库正在做什么或为什么。


GLIBC 错误 23151

GLIBC 错误 23151 https://sourceware.org/bugzilla/show_bug.cgi?id=23151- 具有未关闭文件的分叉进程在退出前执行 lseek,并可能导致父 I/O 中的无限循环。

该错误于 2018 年 5 月 8 日美国/太平洋地区创建,并于 2018 年 5 月 9 日以无效状态关闭。给出的理由是:

请阅读http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01 http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01, 尤其是这一段:

请注意,经过fork(),之前存在一个句柄的地方存在两个句柄。 […]

POSIX

所引用的 POSIX 的完整部分(除了指出 C 标准未涵盖的措辞之外)是这样的:

2.5.1 文件描述符和标准I/O流的交互 http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01

可以通过文件描述符访问打开的文件描述,该文件描述符是使用以下函数创建的open() http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html or pipe() http://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html,或通过流,该流是使用诸如fopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html or popen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html。文件描述符或流都被称为它所引用的打开文件描述的“句柄”;一个打开的文件描述可能有多个句柄。

可以通过显式用户操作创建或销毁句柄,而不会影响底层的打开文件描述。创建它们的一些方法包括fcntl() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html, dup() http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html, fdopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopen.html, fileno() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fileno.html, and fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html。它们至少可以被摧毁fclose() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fclose.html, close() http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html,以及exec http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html功能。

从未在可能影响文件偏移量的操作中使用的文件描述符(例如,read() http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html, write() http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html, or lseek() http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html)不被视为此讨论的句柄,但可能会引起一个句柄(例如,由于fdopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopen.html, dup() http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html, or fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)。此异常不包括流底层的文件描述符,无论是使用fopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html or fdopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopen.html,只要应用程序不直接使用它来影响文件偏移量。这read() http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html and write() http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html函数隐式影响文件偏移量;lseek() http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html明确地影响它。

涉及任何一个句柄(“活动句柄”)的函数调用的结果在 POSIX.1-2017 本卷的其他地方定义,但如果使用两个或多个句柄,并且其中任何一个是流,则应用程序应确保他们的行动如下所述协调一致。如果不这样做,结果是不确定的。

A handle which is a stream is considered to be closed when either an fclose() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fclose.html, or freopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html with non-full(1) filename, is executed on it (for freopen() http://pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html with a null filename, it is implementation-defined whether a new handle is created or the existing one reused), or when the process owning that stream terminates with exit() http://pubs.opengroup.org/onlinepubs/9699919799/functions/exit.html, abort() http://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html, or due to a signal. A file descriptor is closed by close() http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html, _exit() http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html, or the exec() http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html functions when FD_CLOEXEC is set on that file descriptor.

(1) [sic] Using 'non-full' is probably a typo for 'non-null'.

对于要成为活动句柄的句柄,应用程序应确保在最后一次使用句柄(当前活动句柄)和第一次使用第二个句柄(未来活动句柄)之间执行以下操作。然后第二个手柄将成为活动手柄。应用程序影响第一个句柄上的文件偏移量的所有活动都应暂停,直到它再次成为活动文件句柄。 (如果流函数具有影响文件偏移量的底层函数,则该流函数应被视为影响文件偏移量。)

句柄不必位于同一进程中即可应用这些规则。

请注意,经过fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html,之前存在一个句柄的地方存在两个句柄。应用程序应确保,如果两个句柄都可以访问,则它们都处于另一个可以首先成为活动句柄的状态。申请应准备fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html就像更改活动手柄一样。 (如果进程之一执行的唯一操作是exec() http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html函数或_exit() http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html (not exit() http://pubs.opengroup.org/onlinepubs/9699919799/functions/exit.html),在该进程中永远不会访问该句柄。)

对于第一个句柄,适用以下第一个适用条件。执行以下所需操作后,如果句柄仍然打开,应用程序可以将其关闭。

  • 如果它是文件描述符,则无需执行任何操作。

  • 如果对此打开的文件描述符的任何句柄执行的唯一进一步操作是关闭它,则无需执行任何操作。

  • 如果它是未缓冲的流,则无需采取任何操作。

  • 如果它是行缓冲的流,并且写入流的最后一个字节是<newline>(也就是说,就好像一个putc('\n')是该流上的最新操作),无需采取任何操作。

  • 如果它是一个开放用于写入或附加(但不开放用于读取)的流,则应用程序应执行fflush() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html,否则流将被关闭。

  • 如果流打开以供读取并且位于文件末尾(feof() http://pubs.opengroup.org/onlinepubs/9699919799/functions/feof.html是 true),无需采取任何操作。

  • 如果流以允许读取的模式打开,并且底层打开文件描述引用了能够查找的设备,则应用程序应执行fflush() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html,否则流将被关闭。

对于第二个手柄:

  • 如果任何先前的活动句柄已被显式更改文件偏移量的函数使用,除了上面第一个句柄的要求之外,应用程序应执行lseek() http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html or fseek() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html(根据手柄的类型)到适当的位置。

如果在满足上述第一个句柄的要求之前活动句柄不再可访问,则打开文件描述的状态将变为未定义。这可能会发生在诸如fork() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html or _exit() http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html.

The exec() http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html函数使得在调用它们时打开的所有流都不可访问,而与新进程映像可用的流或文件描述符无关。

当遵循这些规则时,无论使用的句柄顺序如何,实现都应确保应用程序(即使是由多个进程组成的应用程序)应产生正确的结果:写入时不会丢失或重复数据,并且所有数据都应写入顺序,除非搜索请求。是否以及在什么条件下所有输入仅被看到一次是由实现定义的。

每个在流上运行的函数都具有零个或多个“底层函数”。这意味着流函数与底层函数共享某些特征,但不要求流函数的实现与其底层函数之间存在任何关系。

Exegesis

那是很难读的!如果您不清楚打开文件描述符和打开文件描述之间的区别,请阅读以下规范open() and fork() (and dup() or dup2() http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html)。的定义文件描述符 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_166 and 打开文件描述 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258如果简洁的话,也是相关的。

在这个问题的代码的上下文中(也适用于读取文件时创建不需要的子进程 https://stackoverflow.com/questions/50244579/),我们有一个打开的文件流句柄仅供读取,尚未遇到 EOF(因此feof()即使读取位置位于文件末尾,也不会返回 true)。

该规范的关键部分之一是:申请应准备fork()就像更改活动手柄一样。

这意味着“第一个文件句柄”概述的步骤是相关的,并且逐步执行这些步骤,第一个适用的条件是最后一个:

  • 如果流以允许读取的模式打开,并且底层打开文件描述引用了能够查找的设备,则应用程序应执行fflush(),否则流将被关闭。

如果你看一下定义fflush() http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html, 你发现:

If stream指向未输入最近操作的输出流或更新流,fflush()应导致该流的任何未写入数据写入文件,[CX] ⌦ 并且底层文件的最后一次数据修改和最后一次文件状态更改时间戳应标记为更新。

对于打开用于读取底层文件描述的流,如果文件尚未位于 EOF,并且该文件能够查找,则底层打开文件描述的文件偏移量应设置为流的文件位置,以及通过以下方式推回流中的任何字符ungetc() http://pubs.opengroup.org/onlinepubs/9699919799/functions/ungetc.html or ungetwc() http://pubs.opengroup.org/onlinepubs/9699919799/functions/ungetwc.html随后未从流中读取的内容将被丢弃(不进一步更改文件偏移量)。 ⌫

目前尚不清楚如果您申请会发生什么fflush()到与不可查找文件关联的输入流,但这不是我们当前关心的问题。但是,如果您正在编写通用库代码,那么您可能需要在执行操作之前知道底层文件描述符是否可查找。fflush()在流上。或者,使用fflush(NULL)让系统执行所有 I/O 流所需的操作,注意这将丢失任何推回的字符(通过ungetc() etc).

The lseek()中显示的操作strace输出似乎正在实施fflush()将打开文件描述的文件偏移量与流的文件位置相关联的语义。

所以,对于这个问题中的代码,似乎fflush(stdin)之前是必要的fork()以确保一致性。不这样做会导致未定义的行为(“如果不这样做,结果是未定义的”)——例如无限循环。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么分叉我的进程会导致文件被无限读取 的相关文章

  • 在 VS2017 下使用 Conan 和 CMake 项目进行依赖管理

    我正在尝试使用 CMake 与 VS2017 集成为 C 设置一个开发环境 以便在 Linux x64 下进行编译 为了更好地管理依赖关系 我选择使用 Conan 但我对这个软件还很陌生 我想知道让 VS2017 识别项目依赖关系的最佳方法
  • 如何使用 zlib 制作 .zip 文件

    我正在阅读zlib的文档 它相当详细 但我读到了这一行 输出数据将位于zlib格式 与 gzip 或zip formats http www zlib net zlib how html http www zlib net zlib how
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • 将字符串转换为正确的 URI 格式?

    有没有简单的方法可以将电子邮件地址字符串转换为正确的 URI 格式 Input http mywebsite com validate email 3DE4ED727750215D957F8A1E4B117C38E7250C33 email
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • 为什么要在 C++ 中使用 typedef?

    可以说我有 set
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • 如何引用解决方案之外的项目?

    我有一个 Visual Studio C 解决方案 其中包含一些项目 其中一个项目需要引用另一个不属于解决方案的项目 一开始我引用了dll
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 类中不允许使用不完整类型,但类模板中允许使用不完整类型

    以下为无效代码 struct foo struct bar bar x error field x has incomplete type struct bar int value 42 int main return foo x valu
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • 将 Google 域链接到 Amazon ec2 服务器

    我正在使用 Amazon EC2 实例来为 node js 应用程序提供服务 我最近通过以下方式购买了域名谷歌域名 https domains google com我想使用该域名来访问我的 node js 应用程序 Google Domai
  • 在AWS SNS(简单通知服务)电子邮件通知中发送html内容

    我在用AWS SNS 简单通知服务 发送电子邮件通知 在电子邮件的内容中 我必须以表格形式表示数据 目前我正在使用简单的文本字符串打印表格 但有格式问题当通过手机和平板电脑等较小屏幕设备访问电子邮件时 表格数据根本无法解释 我希望使用 ht
  • “结构细化中的参数类型可能不会引用该细化之外定义的抽象类型”

    当我编译时 object Test extends App implicit def pimp V xs Seq V new def dummy x V x I get fsc d aoeu go scala go scala 3 err
  • UITableView 中的图像不断重新加载,并且滚动时错误的图像会闪烁

    我创建了一个 UITableView 它根据 URL 请求填充每个单元格 我使用 dispatch queue 来防止 UItableView 冻结 由于某种原因 当我滚动 UITableView 时 图像会闪烁并消失 并填充错误的单元格一
  • 如何循环遍历表来查找数据集?

    我必须找到订单生命周期的时间差 以分钟为单位 即每个订单从收到订单 活动 ID 1 到键入 2 到打印 3 到交付 4 的时间 for eg 我完全迷失了我应该采取哪种方法 用例或 if then 语句 类似于 for every 循环遍历
  • 如何获取多列的groupby总和

    我有一个 pandas 数据框 如下所示 index col1 col2 col3 col4 col5 0 a c 1 2 f 1 a c 1 2 f 2 a d 1 2 f 3 b d 1 2 g 4 b e 1 2 g 5 b e 1
  • C# 中的 MongoDB 地理空间索引

    我一直在尝试使用 C 官方驱动程序创建和查询 MongoDB 但一次又一次地遇到同样的问题 问题是如何用地理信息创建数据 我只是找不到答案 Code MongoUrl url new MongoUrl mongodb xxx xx x xx
  • Docker:打开/certs/domain.crt:权限被拒绝

    我正在尝试设置一个私人 docker 注册表 我正在使用我自己生成的证书 但我的注册表的 docker 日志显示此错误 time 2015 12 08T08 51 54Z level fatal msg open certs domain
  • 使用 MutationObserver 比较新旧文本内容

    我需要比较更改发生之前和之后元素子级内的文本 我可以使用下面的脚本触发函数并返回新值 但我还需要能够访问旧值 changeButton click function var currentValue parseInt changingEle
  • 使用 WPF 实现平滑文本动画(选取框)

    尝试构建具有流畅文本动画的选取框控件 目前的努力包括 使用平移变换 在 Canvas 依赖属性上使用动画 左 右 在自定义依赖属性 点 上使用动画并使用绘图视觉效果 格式化文本 使用 CompositionTarget Rendering
  • 查找到目的地的旅行时间相同的位置:基于运输时间的热图/等值线(反向等时等值线)

    Note 解决方案r questions tagged r or python questions tagged python是所期望的 我正在尝试根据运输时间绘制轮廓 更清楚地说 我想将具有相似旅行时间 假设为 10 分钟间隔 的点聚集到
  • 看板/Scrum 板 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我很好奇其他人在他们的公司中使用什么物理看板 Scrum 板 我理解 由于敏感的商业信息 您可能无法提供董事会的照片 我正在寻找答案你
  • 监控内核注册表更改

    人们能否给我指点 没有双关语 我需要研究的主题才能做到这一点 我并不是真正的 Windows 专家 但我很快就能掌握新概念 我看到了 Mark Russinovich 和 Bryce Cogswell 编写的进程监控程序 http tech
  • 字符串交换适用于 char **,但不适用于 char *

    在这个程序中我交换了前两个名字 include
  • 使用 where 子句的慢查询

    我有以下 sql 查询 只需 1 秒即可执行 select a date b rate c type a value from a inner join b on a id b aid c inner join b id c bid whe
  • 强制

    我在网上看到了很多实现此目的的方法 但我尝试过的所有方法要么会破坏页面上的其他 CSS 要么无法一起工作 在本页http www psyklopz com workbench http www psyklopz com workbench
  • 使用 JavaScript 验证电子邮件地址文本框

    我需要验证用户从文本框出来时输入的电子邮件地址 我已经用谷歌搜索了这个 但我得到了表单验证 JScript 我不需要表单验证 我想要文本框验证 我在 JScript 下写了 但 如果电子邮件无效 则不会返回同一页面 function val
  • 如何使用 Cocoa 或 C++ 在 Mac OS X 中截取屏幕截图

    如何在 Mac OS X 中以编程方式截取桌面区域的屏幕截图 我见过两个有趣的选项 但尚未专业使用 它们是屏幕捕获实用程序和 MacFuse 演示 根据手册页 屏幕捕获实用程序从 10 2 开始就已经存在 并且可以通过使用 NSTask 链
  • 以编程方式配置 Log4NetLoggerFactoryAdapter

    我正在使用 NUnit 来测试一个项目 我想配置我的测试以编程方式设置 Common Logging 以使用 Log4Net 这是我尝试过的 NameValueCollection config new NameValueCollectio
  • 为什么分叉我的进程会导致文件被无限读取

    我已经将整个程序简化为一个简短的主程序来复制该问题 所以请原谅我它没有任何意义 input txt 是一个文本文件 其中包含几行文本 这个简化的程序应该打印这些行 但是 如果调用 fork 程序就会进入无限循环 一遍又一遍地打印文件的内容