#include <stdio.h> #include <pthread.h> #include <segypkg.h> pthread_cond_t notEmpty=PTHREAD_COND_INITIALIZER; pthread_cond_t notFull =PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER; int full=0; int empty=1; int iadd=0; int iremove=0; int n; int n1,n2; int nsum; #define NELEM 100 int list[NELEM]; void *io_thread(void *arg); void *sum_thread(void *arg); segy trio,tr1,tr2; double dtr1[2000],dtr2[2000]; unsigned char *buf; int trsz=(sizeof(float)*2000+240); typedef struct { int id; int *result; }sum_thread_t; int main(int argc,char *argv[]) { pthread_t tio; pthread_t t1,t2; double ret,c1; sum_thread_t tt1,tt2; int it; FILE *fp; memset(dtr1,0,sizeof(double)*2000); memset(dtr2,0,sizeof(double)*2000); buf=(unsigned char*)malloc( trsz*NELEM ); tt1.id=0; tt2.id=1; pthread_create(&tio,NULL,io_thread,NULL); pthread_create(&t1,NULL,sum_thread,&tt1); pthread_create(&t2,NULL,sum_thread,&tt2); pthread_join(tio,NULL); pthread_join(t1,NULL); pthread_join(t2,NULL); printf("here"); /* get final sum */ for (it=0;it<2000;++it) { dtr1[it]+=dtr2[it]; } memset(&tr2,0,sizeof(tr2)); memset(dtr2,0,sizeof(double)*2000); fp=fopen("crp.L1000.su","rb"); while(fgettr(fp,&trio)) { for (it=0;it<2000;++it) { dtr2[it]+=trio.data[it]; } } fclose(fp); ret=0.0; for (it=0;it<2000;++it) { c1=dtr1[it]-dtr2[it]; ret+=(c1*c1); } printf("n= %d ret=%lf nsum=%d n1=%d n2=%d\n",n,ret,nsum,n1,n2); } void *io_thread(void *arg) { printf("in io\n"); int ipill; FILE *fp; fp=fopen("crp.L1000.su","rb"); while (fgettr(fp,&trio)) { n++; pthread_mutex_lock(&mutex); while(full) { pthread_cond_wait(¬Full,&mutex); } empty=0; list[iadd]=1; memcpy(&buf[trsz*iadd],&trio,trsz); iadd++; if (iadd==NELEM) iadd=0; if (iadd==iremove) full=1; pthread_mutex_unlock(&mutex); pthread_cond_signal(¬Empty); } fclose(fp); for (ipill=0;ipill<2;++ipill) { pthread_mutex_lock(&mutex); while(full) { pthread_cond_wait(¬Full,&mutex); } empty=0; list[iadd]=-1; //memcpy(&buf[trsz*iadd],&trio,trsz); iadd++; if (iadd==NELEM) iadd=0; if (iadd==iremove) full=1; pthread_mutex_unlock(&mutex); pthread_cond_signal(¬Empty); } printf("end io\n"); } void *sum_thread(void *arg) { segy tr; int flag=0; sum_thread_t *p=(sum_thread_t*)arg; int id=p->id; int *result=p->result; int it; printf("in thread %d tr=%p\n",id,&tr); while (1) { pthread_mutex_lock(&mutex); while(empty) { pthread_cond_wait(¬Empty,&mutex); } full=0; flag=0; if (list[iremove]==-1) { flag=1; } if (list[iremove]==1) { nsum++; list[iremove]=0; } memcpy(&tr,&buf[iremove*trsz],trsz); iremove++; if (iremove==NELEM) { iremove=0; } if (iremove==iadd) { empty=1; } pthread_mutex_unlock(&mutex); pthread_cond_signal(¬Full); if (flag==1) { break; } if (id==0) n1++; if (id==1) n2++; for (it=0;it<2000;++it) { if (id==0) dtr1[it]+=tr.data[it]; if (id==1) dtr2[it]+=tr.data[it]; } } printf("end thread %d\n",id); }
求和道用 double 如果用 float 那就有误差了,这个害我调试了整整一天。