0

pthreads と相互排除を使用して割り当てを行っています。n 個のプリント サーバーと m 個のプリント クライアントを作成する必要があり、それぞれに 5 つの印刷ジョブがあります。スレッドを作成し、サイズ 4 のキューを介してジョブをプリント サーバーに渡し、ジョブを印刷します (つまり、この場合はビジーな作業)。ジョブを渡し、ジョブを処理するためのコードを次に示します。

これらはクライアントとサーバーのスレッドです

void *PrintClient(void *arg){
int i;
char str[NUMJOBSPERCLIENT][100];

for(i=1;i<NUMJOBSPERCLIENT;i++){
    pthread_mutex_lock(&mutex);
    req.clientID = pthread_self();
    req.fileSize = rand_int(FILEMIN,FILEMAX);
    sprintf(str[i], "File_%d_%d",pthread_self(),i);
    req.fileName = str[i];
    append(req);
    pthread_mutex_unlock(&mutex);
    sleep(rand_int(1,3));
}//for
pthread_exit(NULL);
} // end PrintClient

void *PrintServer(void *arg){

pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
while(count > 0){
    take();
    count = count -1;
}
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
} // end PrintServer

これは、ジョブをキューに追加またはキューから削除するコードです。エラーがここにあり、スレッド自体に関係していることは知っていますが、一生見つけることができません。これまでのところ、デバッガーはほとんど役に立ちませんでした (大学の Linux サーバーでコンパイル エラーを表示していません)。

void append(PrintRequest item){
BoundBuffer[count] = req;
printf("I am client %s\n",req.fileName);
count++;
if(count == BUFSIZE){
    printf("Buffer Size Reached\n");
    pthread_cond_signal(&cond);
}
} // end append

PrintRequest take(){
printf("Printing %s\n", BoundBuffer[count].fileName);
usleep(BoundBuffer[count].fileSize/PRINTSPEED);
printf("Finished Printing %s\n", BoundBuffer[count].fileName);
} // end take
4

1 に答える 1

1

セグメンテーション違反は の周りprintf("Printing %s\n", BoundBuffer[count].fileName);で通知されていると思いますよね?

では、PrintClientファイル名をローカル変数に保存str[][]し、このローカル変数へのポインタをリクエストの 1 つのパラメータとしてコピーしますreq.fileName = str[i];。したがって、 が指すアドレスreq.fileNameは、クライアント スレッドのスタックに割り当てられます。

リクエストがサーバー スレッドPrintServerで処理されると、リクエストを生成したクライアント スレッドが存在しなくなる可能性があります。その結果、 はreq.fileName存在しないアドレスを指し (スタック メモリはクライアント スレッドの終了で既に割り当て解除されています)、 でそのようなアドレスを参照解除するとprintf("Printing %s\n", BoundBuffer[count].fileName);、セグメンテーション違反が通知されます。

于 2013-06-18T06:26:49.190 に答える