我有一个用c++编写的多线程linux应用程序,运行在i.mx6 arm上。我有一个25lc256SPIEEPROM映射到文件系统。在驱动程序级别,写操作相对较慢,在那里可以做的不多。问题是文件函数阻塞其他线程的时间太长了。睡眠补充似乎没有帮助,似乎我将不得不做一些不同的事情,但对我来说还不清楚该改变什么。
从一个线程调用此函数的输出是
EEprom写 EEprom存于522.000000 703.000000 705.000000 723.000000 662596.000000 1328858.000000 捕获-EPIPE snd_pcm_prepare
我想,由于阻塞的线程,捕获-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;
}
发布于 2016-01-29 03:50:04
如果调用fclose()
的线程阻止其他线程长时间运行,那么问题很可能是它在eeprom驱动程序代码中花费了大量时间在内核模式上,清除了挂起的写操作。
有几件事你可以试试:
PREEMPT
配置选项。这将允许线程在运行eeprom驱动程序代码时被抢占。fflush()
,更改代码以更频繁地将写入清除到eeprom (您可能还需要在底层文件描述符上调用fsync()
)。发布于 2016-01-29 02:13:25
看起来问题就在fclose()
中。除非将文件的内容写入磁盘,否则默认情况下,fclose()
不会返回。我相信你可以强迫它尽早返回O_NONBLOCK
,从man 2 open
O_NONBLOCK或O_NDELAY 如果可能,文件将以非阻塞模式打开。对于返回的文件描述符,open()或任何后续操作都不会导致调用进程等待。有关fifo(命名管道)的处理,请参见fifo(7)。有关O_NONBLOCK与强制文件锁和文件租约一起使用的效果的讨论,请参见fcntl(2)。
您可以尝试使用以下方法:
int fd = open(ConfigPath, O_WRONLY | O_NONBLOCK);
FILE * WriteConfig = fdopen(fd, "w");
发布于 2016-01-29 02:30:05
我会试着
fflush( WriteConfig );
就在你
fclose(WriteConfig);
https://stackoverflow.com/questions/35074543
复制相似问题