我首先尝试在main()中打开文件,但是当我的使用者线程尝试使用fputs进行写入或使用fseek更改文件指针时,出现了分段错误。
因此,我尝试打开文件并在线程的关键部分写入文件。这次没有错误,但是文件不正确。除最后一个字符外,每个字符均为“ NUL”符号。
例如:
预期:abcdefg
结果:NULNULNULNULNULNULg
这是我的使用者线程:
void *OUTthread(void *arg)
{
FILE *targetFile;
struct timespec t;
t.tv_sec = 0;
t.tv_nsec = rand()%(TEN_MILLIS_IN_NANOS+1);
nanosleep(&t, NULL);
BufferItem OUTresult;
while(TRUE){
/*** CRITICAL SECTION *************************/
sem_wait(&full);
pthread_mutex_lock( &pt_mutex );
cbRead(&cBuff, &OUTresult);
printf("From buffer: offset %d char %c\n", OUTresult.offset, OUTresult.data);
// The data printed to stdout is correct, so why is it NUL in the file?
if (!(targetFile = fopen(arg, "w+"))) {
printf("could not open output file for writing");
}
if (fseek(targetFile, OUTresult.offset, SEEK_SET) == -1) {
fprintf(stderr, "error setting output file position to %u\n",
(unsigned int) OUTresult.offset);
exit(-1);
}
if (fputc(OUTresult.data, targetFile) == EOF) {
fprintf(stderr, "error writing byte %d to output file\n", OUTresult.data);
exit(-1);
}
fclose(targetFile);
pthread_mutex_unlock( &pt_mutex );
sem_post(&empty); /* signal empty */
/*** END CRITICAL SECTION ****************************/
t.tv_sec = 0;
t.tv_nsec = rand()%(TEN_MILLIS_IN_NANOS+1);
nanosleep(&t, NULL);
}
pthread_exit(0);
}
bufferItem
typedef struct {
char data ;
off_t offset ; // Position of the char.
} BufferItem ;
这是读取循环缓冲区中最旧项目的函数。
void cbRead(CircularBuffer *cb, BufferItem *cbItem) {
*cbItem = cb->cBuffItems[cb->startInd];
cb->startInd = (cb->startInd + 1) % cb->size;
}
如果需要,这是其余的循环缓冲区实现:
// Circular buffer
typedef struct {
int startInd; // Index of first element added to buffer.
int lastInd; // Index of most recent element added to buffer.
int size; // Number of elements in circular buffer.
BufferItem *cBuffItems; // Circular buffer items.
} CircularBuffer;
void addItem(CircularBuffer *cBuff, BufferItem *cbItem) {
cBuff->cBuffItems[cBuff->lastInd] = *cbItem;
cBuff->lastInd = ( ((cBuff->lastInd) + 1) % cBuff->size);
if (cBuff->lastInd == cBuff->startInd)
{
cBuff->startInd = (cBuff->startInd + 1) % cBuff->size; // Overwriting full buffer.
}
}
void initializeBuffer(CircularBuffer *cBuff, int size) {
cBuff->cBuffItems = calloc(size + 1, sizeof(BufferItem));
cBuff->size = size + 1;
cBuff->startInd = 0;
cBuff->lastInd = 0;
}
int cbIsEmpty(CircularBuffer *cb) {
return cb->lastInd == cb->startInd;
}
在我看来,问题是使用“ w +”模式打开文件。w +丢弃先前的内容。消费者每次(再次)打开文件时,都会得到被截断的文件,然后寻找位置并写一个字符。这会丢弃所有先前的数据,因此最后获胜,并解释了为什么您看到最后一个消费者的角色,并为每个先前的“搜索”填充了空值
http://www.cplusplus.com/reference/cstdio/fopen/
尝试使用“ r +”打开,如果调用失败,然后回退到“ w +”(或者,如果您不需要更新以前的内容,则仅使用一个带有“ a”的fopen)。您也可以先使用stat()检查是否存在,尽管这实际上是fopen(“ r +”)所做的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句