2013-04-10 69 views
-2

我已将下列程序作为我学术项目的一部分。由于我无法确定实际问题,因此我已经给出了整个程序。下面多线程程序中的分段错误C

#include<stdio.h> 
#include<math.h> 
#include<pthread.h> 
//Structure for getting dam details 
struct dam 
{ 
    float max_height; 
    float min_height; 
    float sto_capacity; 
    float pro_capacity; 
    float stn_const; 
    float crnt_lvl; 
    float delay; 
    float crnt_lvl_min; 
    float crnt_lvl_max; 
    float unit_vol; 
    float water_req; 
    float work_hr; 
    int work_hr_int; 
}; 
//global variables 
int n, i, extra_w_hr_int, extra_w_hr_ref, j, k, flag, l, m, swap, pos=11, h, main_flag=1, days_count=0, temp_extra_w_hr_ref; 
int jj, k1, flag1, l1, m1, swap1, g=0; 
float extra_w_hr, extra_height, diff_level, extra_water; 
int rank[24]; 
int rank1[24]; 
float rate[24]; 
float water_pu[24]; 
float sum_rate1[24]; 
float avg_rate1[24]; 
float std_dev_rate1[24]; 
float temp_rate1[24]; 
float sum_rate[24]; 
float avg_rate[24]; 
float std_dev_rate[24]; 
float temp_rate[24]; 
struct dam dam_obj[10]; 
pthread_t inner_thread[10]; 
//Thread for increasing water in lower dam after delay 
void *inner_function(void *no) 
{ 

    int *num = no; 
    if(*num != (n-1)) 
    { 

     sleep(dam_obj[*num-1].delay); 

    } 
    else if(*num == (n-1)) 
    { 

     sleep(dam_obj[*num].delay); 

    } 
    dam_obj[*num+1].unit_vol = dam_obj[*num+1].sto_capacity/(dam_obj[*num+1].max_height - dam_obj[*num+1].min_height); 
    extra_height = extra_water/dam_obj[*num+1].unit_vol; 
    dam_obj[*num+1].crnt_lvl+=extra_height; 
    pthread_exit(NULL); 

} 
//Thread for forcasting 7 day details 
void *days_function() 
{ 

    while(days_count<7) 
    { 

     h=n-2; 

     while(h>=(pos-1)) 
     { 

      printf("Day-%d\tWorking Hours of dam %d:\t18hrs to 22hrs\n", days_count+1, h); 
      dam_obj[h].water_req = (dam_obj[h].pro_capacity*dam_obj[h].work_hr)/(1000*dam_obj[h].stn_const); 
      if((h-1)>-1) 
      { 

       dam_obj[h-1].work_hr = dam_obj[h].water_req*1000*dam_obj[h].stn_const/dam_obj[h-1].pro_capacity; 
       dam_obj[h-1].work_hr_int = dam_obj[h-1].work_hr*10; 
       temp_extra_w_hr_ref = dam_obj[h-1].work_hr_int%10; 
       dam_obj[h-1].work_hr_int/=10; 
       if(temp_extra_w_hr_ref>2) 
       { 

        dam_obj[h-1].work_hr_int++; 

       } 

       dam_obj[h-1].work_hr_int-=4; 

       //calculate the average and standard deviation of the rates 
       jj=0; 
       k1=1; 
       flag1=1; 
       while(flag1=1) 
       { 

        if(jj==0 && k1==0) 
        { 

         flag1=0; 
         break; 

        } 

        if(jj>=18 && jj<=22 && (jj+dam_obj[h-1].work_hr_int)>=18 && (jj+dam_obj[h-1].work_hr_int)<=22) 
        { 

         rank1[jj]=25; 
         jj++; 
         sum_rate1[jj]=0; 
         avg_rate1[jj]=0; 
         std_dev_rate1[jj]=0; 
         continue; 

        } 

        rank1[jj]=jj; 
        k1=0; 
        sum_rate1[jj] = 0; 
        for(l1=0;l1<dam_obj[h-1].work_hr_int;l1++) 
        { 

         m1 = jj+l1; 
         if(m1>23) 
         { 

          m1-=24; 

         } 
         sum_rate1[jj]+=rate[m1]; 

        } 

        avg_rate1[jj]=sum_rate1[jj]/extra_w_hr_int; 

        for(l1=0;l1<dam_obj[h-1].work_hr_int;l1++) 
        { 

         m1 = jj+l1; 
         if(m1>23) 
         { 

          m1-=24; 

         } 

         temp_rate1[m1]=rate[m1]; 
         temp_rate1[m1]=pow((temp_rate1[m1]-avg_rate1[m1]),2); 
         std_dev_rate1[jj]+=temp_rate1[m1]; 

        } 

        jj++; 

        if(jj>23) 
        { 

         jj-=24; 

        } 

       } 

       //Sorting the values 
       for(jj=0;jj<(n-1);jj++) 
       { 

        for(l1=0;l1<n-jj-1;l1++) 
        { 

         if((avg_rate1[l1]>avg_rate1[l1+1]) || ((avg_rate1[l1]==avg_rate1[l1+1]) && (std_dev_rate1[l1]>std_dev_rate1[l1+1]))) 
         { 

          swap1=rank1[l1]; 
          rank1[l1]=rank[l1+1]; 
          rank[l1+1]=swap1; 

         } 

        } 

       } 

       printf("Day-%d\tWorking Hours of dam %d:\t18hrs to 22hrs\tand\t%dhrs to %dhrs\n", days_count+1, h-1, rank1[0], rank1[0]+dam_obj[h-1].work_hr_int); 

      } 

      h--; 

     } 

     while(g<(pos-1)) 
     { 

      printf("Day-%d\tWorking Hours of dam 1:\t18hrs to 22hrs\n", days_count+1); 
      dam_obj[g].water_req = dam_obj[g].pro_capacity*dam_obj[g].work_hr/(1000*dam_obj[g].stn_const); 
      dam_obj[g+1].work_hr = dam_obj[g].water_req*1000*dam_obj[g+1].stn_const/dam_obj[g+1].pro_capacity; 
      dam_obj[g+1].work_hr_int = dam_obj[g+1].work_hr*10; 
      temp_extra_w_hr_ref = dam_obj[g+1].work_hr_int%10; 
      dam_obj[g+1].work_hr_int/=10; 
      if(temp_extra_w_hr_ref>2) 
      { 

       dam_obj[g+1].work_hr_int++; 

      } 
      dam_obj[g+1].work_hr_int-=4; 

      //calculate the average and standard deviation of the rates 
      jj=0; 
      k1=1; 
      flag1=1; 
      while(flag1=1) 
      { 

       if(jj==0 && k1==0) 
       { 

        flag1=0; 
        break; 

       } 

       if(jj>=18 && jj<=22 && (jj+dam_obj[g+1].work_hr_int)>=18 && (jj+dam_obj[g+1].work_hr_int)<=22) 
       { 

        rank1[jj]=25; 
        jj++; 
        sum_rate1[jj]=0; 
        avg_rate1[jj]=0; 
        std_dev_rate1[jj]=0; 
        continue; 

       } 

       rank1[jj]=jj; 
       k1=0; 
       sum_rate1[jj] = 0; 
       for(l1=0;l1<dam_obj[g+1].work_hr_int;l1++) 
       { 

        m1 = jj+l1; 
        if(m1>23) 
        { 

         m1-=24; 

        } 
        sum_rate1[jj]+=rate[m1]; 

       } 

       avg_rate1[jj]=sum_rate1[jj]/extra_w_hr_int; 

       for(l1=0;l1<dam_obj[g+1].work_hr_int;l1++) 
       { 

        m1 = jj+l1; 
        if(m1>23) 
        { 

         m1-=24; 

        } 

        temp_rate1[m1]=rate[m1]; 
        temp_rate1[m1]=pow((temp_rate1[m1]-avg_rate1[m1]),2); 
        std_dev_rate1[jj]+=temp_rate1[m1]; 

       } 

       jj++; 

       if(jj>23) 
       { 

        jj-=24; 

       } 

      } 

      //Sorting the values 
      for(jj=0;jj<(n-1);jj++) 
      { 

       for(l1=0;l1<n-jj-1;l1++) 
       { 

        if((avg_rate1[l1]>avg_rate1[l1+1]) || ((avg_rate1[l1]==avg_rate1[l1+1]) && (std_dev_rate1[l1]>std_dev_rate1[l1+1]))) 
        { 

         swap1=rank1[l1]; 
         rank1[l1]=rank[l1+1]; 
         rank[l1+1]=swap1; 

        } 

       } 

      } 

      printf("Day-%d\tWorking Hours of dam %d:\t18hrs to 22hrs\tand\t%dhrs to %dhrs\n", days_count+1, g+2, rank1[0], rank1[0]+dam_obj[g+1].work_hr_int); 
      g++; 

     } 

     dam_obj[n-1].water_req = dam_obj[g].water_req - dam_obj[g-1].water_req; 
     dam_obj[n-1].work_hr = dam_obj[n-1].water_req*1000*dam_obj[n-1].stn_const/dam_obj[n-1].pro_capacity; 
     dam_obj[n-1].work_hr_int = dam_obj[n-1].work_hr*10; 
     temp_extra_w_hr_ref = dam_obj[n-1].work_hr_int%10; 
     dam_obj[n-1].work_hr_int/=10; 
     if(temp_extra_w_hr_ref>2) 
     { 

      dam_obj[n-1].work_hr_int++; 

     } 
     dam_obj[n-1].work_hr_int-=4; 

     //calculate the average and standard deviation of the rates 
     jj=0; 
     k1=1; 
     flag1=1; 
     while(flag1=1) 
     { 

      if(jj==0 && k1==0) 
      { 

       flag1=0; 
       break; 

      } 

      if(jj>=18 && jj<=22 && (jj+dam_obj[n-1].work_hr_int)>=18 && (jj+dam_obj[n-1].work_hr_int)<=22) 
      { 

       rank1[jj]=25; 
       jj++; 
       sum_rate1[jj]=0; 
       avg_rate1[jj]=0; 
       std_dev_rate1[jj]=0; 
       continue; 

      } 

      rank1[jj]=jj; 
      k1=0; 
      sum_rate1[jj] = 0; 
      for(l1=0;l1<dam_obj[n-1].work_hr_int;l1++) 
      { 

       m1 = jj+l1; 
       if(m1>23) 
       { 

        m1-=24; 

       } 
       sum_rate1[jj]+=rate[m1]; 

      } 

      avg_rate1[jj]=sum_rate1[jj]/extra_w_hr_int; 

      for(l1=0;l1<dam_obj[h-1].work_hr_int;l1++) 
      { 

       m1 = jj+l1; 
       if(m1>23) 
       { 

        m1-=24; 

       } 

       temp_rate1[m1]=rate[m1]; 
       temp_rate1[m1]=pow((temp_rate1[m1]-avg_rate1[m1]),2); 
       std_dev_rate1[jj]+=temp_rate1[m1]; 

      } 

      jj++; 

      if(jj>23) 
      { 

       jj-=24; 

      } 

     } 

     //Sorting the values 
     for(jj=0;jj<(n-1);jj++) 
     { 

      for(l1=0;l1<n-jj-1;l1++) 
      { 

       if((avg_rate1[l1]>avg_rate1[l1+1]) || ((avg_rate1[l1]==avg_rate1[l1+1]) && (std_dev_rate1[l1]>std_dev_rate1[l1+1]))) 
       { 

        swap1=rank1[l1]; 
        rank1[l1]=rank[l1+1]; 
        rank[l1+1]=swap1; 

       } 

      } 

     } 

     printf("Day-%d\tWorking Hours of dam %d:\t18hrs to 22hrs\tand\t%dhrs to %dhrs\n", days_count+1, n-1, rank1[0], rank1[0]+dam_obj[n-1].work_hr_int); 


    } 

    pthread_exit(NULL); 

} 
//Thread function for working of dams 
void *dam_function() 
{ 

    diff_level = dam_obj[i].crnt_lvl - dam_obj[i].crnt_lvl_max; 
    dam_obj[i].unit_vol = dam_obj[i].sto_capacity/(dam_obj[i].max_height - dam_obj[i].min_height); 
    extra_water = diff_level * dam_obj[i].unit_vol; 
    water_pu[i] = dam_obj[i].pro_capacity/(dam_obj[i].stn_const * 1000); 
    extra_w_hr = extra_water/water_pu[i]; 
    extra_w_hr_int = extra_w_hr*10; 
    extra_w_hr_ref = extra_w_hr_int%10; 
    extra_w_hr_int/=10; 
    if(extra_w_hr_ref>2) 
    { 

     extra_w_hr_int++; 

    } 

    //calculate the average and standard deviation of the rates 
    j=0; 
    k=1; 
    flag=1; 
    while(flag=1) 
    { 

     if(j==0 && k==0) 
     { 

      flag=0; 
      break; 

     } 

     if(j>=18 && j<=22 && (j+extra_w_hr_int)>=18 && (j+extra_w_hr_int)<=22) 
     { 

      rank[j]=25; 
      j++; 
      sum_rate[j]=0; 
      avg_rate[j]=0; 
      std_dev_rate[j]=0; 
      continue; 

     } 

     rank[j]=j; 
     k=0; 
     sum_rate[j] = 0; 

     for(l=0;l<extra_w_hr_int;l++) 
     { 

      m = j+l; 
      if(m>23) 
      { 

       m-=24; 

      } 
      sum_rate[j]+=rate[m]; 

     } 

     avg_rate[j]=sum_rate[j]/extra_w_hr_int; 
     std_dev_rate[j]=0; 

     for(l=0;l<extra_w_hr_int;l++) 
     { 

      m = j+l; 
      if(m>23) 
      { 

       m-=24; 

      } 
      temp_rate[m]=rate[m]; 
      temp_rate[m]=pow((temp_rate[m]-avg_rate[m]),2); 
      std_dev_rate[j]+=temp_rate[m]; 

     } 

     j++; 

     if(j>23) 
     { 

      j-=24; 

     } 

    } 

    //Sorting the values 
    for(j=0;j<(n-1);j++) 
    { 

     for(l=0;l<n-j-1;l++) 
     { 

      if((avg_rate[l]>avg_rate[l+1]) || ((avg_rate[l]==avg_rate[l+1]) && (std_dev_rate[l]>std_dev_rate[l+1]))) 
      { 

       swap=rank[l]; 
       rank[l]=rank[l+1]; 
       rank[l+1]=swap; 

      } 

     } 

    } 

    printf("Hours of extra running: %d\nExtra Working Hours for dam-%d: %d Hours - %d Hours\n", extra_w_hr_int, i, rank[0], rank[0]+extra_w_hr_int); 

    if(i+1<n) 
    { 

     pthread_create (&inner_thread[i], NULL, (void *) &inner_function, &i); 
     if(i == pos) 
     { 

      pthread_create (&inner_thread[pos], NULL, (void *) &inner_function, &pos); 

     } 

    } 

    pthread_exit(NULL); 

} 

int main() 
{ 

    pthread_t thread[10],days_thread; 
    FILE *file = fopen ("values.txt", "r"); 
    dam_obj[n-1].work_hr = 4; 
    dam_obj[0].work_hr = 24; 
    //printf("Enter the number of dams:\t\t"); 
    fscanf(file, "%d\n",&n); 
    //printf("\n\nThe branched dam should be given as the \'n\'th dam in the set\n\n\n"); 
    for(i=0;i<n;i++) 
    { 

     //printf("Enter the maximum height of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].max_height);  
     //printf("Enter the minimum height of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].min_height);  
     //printf("Enter the storage capacity of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].sto_capacity); 
     //printf("Enter the production capacity of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].pro_capacity); 
     //printf("Enter the station constant of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].stn_const); 
     //printf("Enter the current level of dam-%d:\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].crnt_lvl); 
     //printf("Enter the time delay of dam-%d:\t\t",i+1); 
     fscanf(file, "%f\n",&dam_obj[i].delay); 

    } 

    //printf("Enter the rates for the following hours:\n"); 
    for(i=0;i<24;i++) 
    { 

     //printf("%d-%d:\t\t\t",i,i+1); 
     fscanf(file, "%f\n",&rate[i]); 

    } 

    if(n>2) 
    { 

     //printf("Enter the position at which the stage occurs:\t"); 
     fscanf(file, "%d\n",&pos); 

    } 

    for(i=0;(i<n && days_count<7);i++) 
    { 

     dam_obj[i].crnt_lvl_min=dam_obj[i].max_height * 0.6; 
     dam_obj[i].crnt_lvl_max=dam_obj[i].max_height * 0.8; 

     //If the current level is greater than allowed maximum level 
     if(dam_obj[i].crnt_lvl_max < dam_obj[i].crnt_lvl) 
     { 
      pthread_create (&thread[i], NULL, (void *) &dam_function, NULL); 
      if(i==(n-1)) 
      { 

       i = -1; 
       days_count++; 

      } 

     } 

     //Normal Working Condition 
     else if(((dam_obj[i].crnt_lvl<dam_obj[i].crnt_lvl_max) && (dam_obj[i].crnt_lvl>dam_obj[i].crnt_lvl_min)) && (main_flag == 1)) 
     { 

      main_flag=0; 
      pthread_create (&days_thread, NULL, (void *) &days_function, NULL); 

     } 

    } 

    pthread_exit(NULL); 

} 

文件的内容给出:

5 
1758.69 
1735.836 
7.787 
28 
1.263 
1758.69 
2 
847.6 
844.86 
1.614 
36 
.79 
847.05 
4 
456.59 
444 
5.557 
55 
.41 
452.9 
3 
253 
237.74 
4.55 
116 
.46 
247.3 
0 
707.745 
678.8 
47.4 
32 
.472 
703.8 
2 
7 
5 
6 
3 
8 
3 
6 
4 
5 
7 
9 
1 
3 
2 
4 
5 
7 
8 
4 
6 
7 
3 
5 
9 
3 

我编译使用gcc -o project project.c -pthread -lpthread -lm 在Linux中程序但在运行它返回只是一个Segmentation Fault。所以,我编译的代码使用gdb调试,之后上运行,GDB结果如下:

Starting program: /home/anver/project 
[Thread debugging using libthread_db enabled] 
[New Thread 0xb7e2db70 (LWP 3778)] 
[New Thread 0xb762cb70 (LWP 3779)] 
[New Thread 0xb6e2bb70 (LWP 3780)] 
[New Thread 0xb662ab70 (LWP 3781)] 

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb762cb70 (LWP 3779)] 
0x08049cd1 in dam_function() at project-file.c:504 
504    std_dev_rate[j]+=temp_rate[m]; 

后,当我打印的J,L值和M我想通了,我得到非常高的值对于j,l和m来说,这是预计不会超过23的。无论如何我可以解决这个问题吗?提前致谢。

+5

没有人会花费他们的下午看600多行代码。您有责任提供最小的,可口的测试用例。 – 2013-04-10 18:35:08

+1

你给出了发布这个代码墙的基本原理,你不知道问题出在哪里,但没有gdb为你做这件事? ('std_dev_rate [j] + = temp_rate [m];') – antonijn 2013-04-10 18:35:53

+0

我给出了整个代码,因为我找不出实际问题在哪里。正如你所看到的,程序中使用了很多变量和线程,我无法弄清楚任何线索。我已经包含了gdb的结果,所以很容易检查出来。 – 2013-04-10 18:37:32

回答

0

pthreads标准指定在一个线程上访问某个变量时,或者可能在另一个线程中修改该变量是未定义的行为。您的函数days_function可以在变量days_count中执行此操作,以及许多其他地方的其他变量。

说白了,它看起来像你不知道如何正确使用线程。