linux - fwrite fopen 阻塞线程

标签 linux pthreads

我有一个用 C 语言编写的多线程 Linux 应用程序,运行在 i.mx6 ARM 上。我有一个映射到文件系统的 25lc256 spi eeprom。驱动程序级别的写入相对较慢,在那里可以做的事情不多。问题是文件函数阻塞其他线程的时间太长了。 usleep 添加似乎没有帮助,看来我必须做一些不同的事情,但我不清楚要改变什么。

从一个线程调用这个函数的输出是

EEprom write
EEprom saved in 522.000000 703.000000 705.000000 723.000000 662596.000000 1328858.000000
Capture -EPIPE snd_pcm_prepare

我想 Capture -EPIPE snd_pcm_prepare 来自音频缓冲区由于线程阻塞而运行不足的线程。

int SaveCurrentConfig(void) {//EEPROM
    int r = 1;
    struct timeval tvs, tv1, tv2, tv3, tv4, tv5, tv6;
    gettimeofday(&tvs, NULL);
    printf("EEprom write\n");
    pthread_mutex_lock(&eepromconfigmutex);
    {
        char * ConfigXml = BuildXmlConfig();
        FILE * WriteConfig = fopen(ConfigPath, "w");
        if (WriteConfig == NULL) {
            MyLog("Unable to open eeprom %s\n", strerror(errno));
            r = 0;
            goto badfinish;
        }
        gettimeofday(&tv1, NULL);
        size_t len = strlen(ConfigXml);
        unsigned short CRC = ComputeChecksum(ConfigXml, len);
        fwrite((char*) &len, 1, sizeof (size_t), WriteConfig);
        gettimeofday(&tv2, NULL);
        fwrite((char*) &CRC, 1, 2, WriteConfig);
        gettimeofday(&tv3, NULL);
        fwrite(ConfigXml, 1, strlen(ConfigXml), WriteConfig);
        gettimeofday(&tv4, NULL);
        fseek(WriteConfig, ConfigOffset2, SEEK_SET);
        fwrite((char*) &len, 1, sizeof (size_t), WriteConfig);
        fwrite((char*) &CRC, 1, 2, WriteConfig);
        fwrite(ConfigXml, 1, strlen(ConfigXml), WriteConfig);
        gettimeofday(&tv5, NULL);
        fclose(WriteConfig);
badfinish:
        free(ConfigXml);
    }
    pthread_mutex_unlock(&eepromconfigmutex);
    gettimeofday(&tv6, NULL);
    double diff1 = time_diff(tvs, tv1);
    double diff2 = time_diff(tvs, tv2);
    double diff3 = time_diff(tvs, tv3);
    double diff4 = time_diff(tvs, tv4);
    double diff5 = time_diff(tvs, tv5);
    double diff6 = time_diff(tvs, tv6);

    printf("EEprom saved in %f  %f  %f  %f  %f  %f\n", diff1, diff2, diff3, diff4, diff5, diff6);
    return r;
}

最佳答案

如果调用 fclose() 的线程长时间阻止其他线程运行,那么问题很可能是它在 eeprom 驱动程序代码内的内核模式下花费了大量时间,刷新出挂起的写入。

有几件事你可以尝试:

  • 确保您运行的内核选择了 PREEMPT 配置选项。这将允许线程在运行 eeprom 驱动程序代码时被抢占。
  • 结合第一个建议,为声音线程设置更高的调度优先级(和/或为 eeprom 写入线程设置更低的调度优先级)。
  • 更改您的代码,通过在写入较小的数据 block 后调用 fflush() 来更频繁地刷新对 eeprom 的写入(您可能还需要调用 fsync() 在底层文件描述符上)。

关于linux - fwrite fopen 阻塞线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35074543/

相关文章:

linux - 未知主机名错误 - Raspbian

android - 如何在 linux 上设置用于命令行开发的 android SDK?

c - pthread_join() 期间的段错误

c - 在多线程环境中遵循指针

c - 线程到多搜索文件

linux - `|` 和 `mknod pipe p` 是做同样的事情吗?

c++ - 在套接字编程中从服务器捕获客户端导出

c - "make"编译写在 "cc ex1.c -o ex1"文件中的代码,为什么我们使用 "exe1.c"命令

c - pthread_barrier 不符合我的预期

使用 PThreads 的 C 生产者-消费者