構造体を介して呼び出された関数に複数のパラメーターを渡す単純なプログラムを pthreads で作成しました。次の 2 つのプログラムについて考えてみましょう。
プログラム 1 :
#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
struct args{
long long val1;
int val2;
};
void *hello(void* threadid){
struct args *tid;
tid=(struct args*)threadid;
printf("thread %lld\n",tid->val1);
pthread_exit(NULL);
}
int main(){
pthread_t threads[20];
int i;
for(i=0;i<20;i++){
// ***** specific memory given to the struct *****
struct args* a1=(struct args*)malloc(sizeof(struct args));
a1->val1=i;
a1->val2=i+1;
int ret=pthread_create(&threads[i],NULL,hello,(void*)a1);
if(ret){
printf("error code %d for %d\n",ret,i);
}
}
pthread_exit(NULL);
}
期待どおりに出力を印刷し、いくつかの順列0..19
一方、プログラム p2 を検討してください。
#include <pthread.h>
#include <stdio.h>
struct args{
long long val1;
int val2;
};
void *hello(void* threadid){
struct args *tid;
tid=(struct args*)threadid;
printf("thread %lld\n",tid->val1);
pthread_exit(NULL);
}
int main(){
pthread_t threads[20];
int i;
for(i=0;i<20;i++){
// ***** struct made like normal declarations *****
struct args a1;
a1.val1=i;
a1.val2=i+1;
int ret=pthread_create(&threads[i],NULL,hello,(void*)&a1);
if(ret){
printf("error code %d for %d\n",ret,i);
}
}
pthread_exit(NULL);
}
このプログラムには、次のような繰り返しの不完全なエントリがあります
thread 3
thread 5
thread 3
thread 4
thread 3
thread 6
thread 7
thread 8
thread 9
thread 10
thread 11
thread 12
thread 13
thread 15
thread 15
thread 16
thread 17
thread 18
thread 19
thread 19
構造体のインスタンス化がこの種のオーバーラップを直接引き起こすのはなぜですか? C はループのたびに新しいメモリ ブロックを提供するべきではありませんか?