我有一个用 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/