私は、ファイルからギガバイトのシーケンスをロードして処理する必要があるプロジェクトに取り組んでいます。大量のデータを扱っているため、RAMに保存できません。したがって、1つのスレッドを使用してこのファイルからデータをロードし、キューに保存し、1つのスレッドを使用して、キューに何かがあることを検出したら、それを一時ファイルにアンロードします。
これを行うのに問題があります。競合状態があるようです。動作する場合もあれば、セグメンテーション違反を返す場合もあります。
バグのある最小限のコード例を書きました。
これは私のキューコードです:
//####################
// STRUCTS
//####################
struct queue_item{
char *seq;
struct queue_item *prox;//Next element
};
typedef struct queue_item QueueItem;
struct Queue{
QueueItem *first;//First element on queue
QueueItem *end;//Last element on queue
int size;//Queue size
};
typedef struct Queue Queue;
//####################
Queue* create_queue(){
Queue *f;
f = (Queue*)malloc(sizeof(Queue));
f->size = 0;
return f;
}
QueueItem* new_queue_item(char *seq){
QueueItem* new;
int n;
n = strlen(seq);
new = (QueueItem*)malloc(sizeof(QueueItem));
new->seq = (char*)malloc((n+1)*sizeof(char));
strcpy(new->seq,seq);
return new;
}
void enqueue(Queue *f,char *seq){
QueueItem* new;
new = new_queue_item(seq);
switch(f->size){
case 0:
f->first = new;
break;
case 1:
f->end = new;
f->first->prox = f->end;
break;
default:
f->end->prox = new;
f->end = new;
break;
}
f->size = f->size + 1;
return;
}
char* dequeue(Queue *f){
QueueItem *hold;
char *seq;
if(f->size > 0){
hold = f->first;
seq = f->first->seq;
f->first = f->first->prox;
free(hold);
f->size--;
}
return seq;
}
int queue_size(Queue *f){
return f->size;
}
void seq_to_file(char *seq,FILE *f){
if(seq != NULL){
fputs(seq,f);
free(seq);
}
return;
}
これは私のメインコードです:
Queue *f;
int i;
int end_flag;
char *seq;
f = create_queue();
end_flag = 0;
#pragma omp parallel shared(f) shared(end_flag)
{
#pragma omp sections
{
#pragma omp section
{
FILE *tmp;
tmp = fopen("tmp","w");
while(!end_flag){
if(queue_size(f) > 0)
seq_to_file(dequeue(f),tmp);
}
fclose(tmp);
}
#pragma omp section
{
seq = (char*)malloc(21*sizeof(char));
strcpy(seq,"ABCDEFGHIJKLMNOPQRST");
for(i=0;i < NSEQS;i++)
enqueue(f,seq);
end_flag = 1;
}
}
}
私が検出したいくつかのエラー:
1-new_queue_item()行のmallocエラー:new-> seq =(char *)malloc((n + 1)* sizeof(char));
*glibcが検出されました* /home / pedro /Dropbox/Programação/C/ Queue / fila_teste:ダブルフリーまたは破損(出力):0x00000000006f3bd0 * glibcが検出されました/ home / pedro /Dropbox/Programação/C/ Queue / fila_teste:malloc():メモリ破損(高速):0x00000000006f3b70 *
2-new_queu_item()行のmallocエラー:new =(QueueItem *)malloc(sizeof(QueueItem));
3-seq_to_file()行のフリーエラー:free(seq);
*glibcが検出されました* /home / pedro /Dropbox/Programação/C/ Queue / fila_teste:ダブルフリーまたは破損(出力):0x0000000000cdd3f0 *
gdbで確認すると、次のようになります。(gdb)print * f $ 16 = {first = 0x0、end = 0x611180、size = 426}
この3番目のエラーにより、これは実際には競合状態の状況であると思います。
「end_flag」でセマフォをシミュレートしようとしましたが、十分ではないと思います。また、「クリティカル」句と「アトミック」句は、メモリではなくコード領域へのアクセスのみを保護するため、ここで役立つとは思わないでください。
この問題を解決する方法はありますか?