我首先尝试在main()中打开文件,但是当我的消费者线程尝试使用fputs写入或使用fseek更改文件指针时,我收到了分段错误。
所以我尝试打开文件并写入线程临界区内的文件。这次没有错误,但文件不正确。除最后一个字符外的每个字符都是“NUL”符号。
例如:
预期:abcdefg
结果:NULNULNULNULNULNULNULg
这是我的消费者主题:
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;
}
答案 0 :(得分:3)
对我来说,问题是打开文件" w +"模式。 w +丢弃以前的内容。每当您的消费者打开文件(再次)时,您会得到一个截断的文件,然后您寻找一个位置并写一个字符。这会丢弃所有以前的数据,所以最后会获胜,并解释为什么你会看到上一个消费者的角色,每个先前的消息都为空前填充"寻找"
http://www.cplusplus.com/reference/cstdio/fopen/
尝试打开" r +"如果该呼叫失败,则回到" w +" (或者只使用单个fopen和#34; a"如果你不需要更新以前的内容)。你也可以先用stat()来检查是否存在,尽管这实际上是fopen(" r +")的作用。