无法从传递给pthread

时间:2016-12-05 01:40:53

标签: c++

我坚持这个,似乎无法弄清楚发生了什么。对于后台,我试图将一个结构体传递给3个pthreads,然后在线程中修改该结构,然后将每个结构存储回主线程,并将每个结构得到的部分结果加起来以加速这部分我的代码似乎是性能的主要瓶颈。我在用C编写的另一个项目中使用了与此非常类似的代码,但是当我将它复制到这个C ++程序并修改它以适应这个问题时,我遇到了一些奇怪的错误。

首先,我必须制作一些我不必在C中制作的演员表,以便进行编译。由于我在类中包含thread_work函数作为方法,因此它将类型视为(void *(AIShell :: *)(void *),因此我需要将其转换为(void *(*)(void *),它允许它编译和运行,但它给了我一个编译器警告。我把它作为方法而不仅仅是一个函数包含的原因是我可以从这个中调用另一个类方法,所以它是必需的。是否有任何方式我都应该修改我的代码以使其消失,或者这只是在类中使用我的线程函数的一个不幸的副作用?

AIShell.cpp: In member function ‘double AIShell::heuristic(int**)’:
AIShell.cpp:173:78: warning: converting from ‘void* (AIShell::*)(void*)’ to ‘void* (*)(void*)’ [-Wpmf-conversions]
   th = pthread_create(&new_threads[i], &attr, (void * (*)(void *)) &AIShell::thread_work, (void *) (se+i));

其次,最重要的是我在运行代码时遇到了段错误。我已经缩小了问题发生的位置,每当我尝试访问我传入线程的结构成员时(即执行se-> start_count),它就会发生在我的thread_work函数中:

125 struct start_end
126 {
127     int ** board;
128     int start_col;
129     int end_col;
130     int start_row;
131     int end_row;
132     double total;
133 };
134
135 void * AIShell::thread_work(void * arg)
136 {
137     struct start_end * se = (struct start_end *) malloc(sizeof(struct start_end));
138     se = (struct start_end *) arg;
139     printf("\nse->total = %lg; se->start_row = %d; se->start_col = %d\n\n", se->total, se->start_row, se->start_c    ol);
140     fflush(stdout);
141     for (int row = se->start_row; row != se->end_row; row++)
142     {
143         for (int col = se->start_col; col != se->end_col; col++)
144         {
145             se->total += check8(se->board, col, row);
146         }
147     }
148     printf("asdfasdfasfdasdfasdfasdfasdfasdfasdfasdf\n");
149     fflush(stdout);
150     pthread_exit((void *)se);
151 }

当它到达代码的这部分时,这是每个线程运行的代码,它最初在第141行开始时失败,但在第139行添加print语句后,它在那里失败,这证实了问题在于引用结构成员。

但是,如果我添加"&"之前" arg"在138行,所以它看起来像这样:

138     se = (struct start_end *) &arg;

它不会再发生段错误,但它会获得垃圾值,这会破坏我以后的一些代码。据我所知,我在将结构传递给线程之前正确地为结构赋值,所以我不确定这里发生了什么。

此代码是充当"主线程"的方法。初始化结构,产生其他线程,并且应该从每个线程中获取结果并将它们相加以获得最终结果。它也充当了这个本身的线程所以我在这里使用了类似的代码段,我在上面的函数中做了所以我将使用我的所有资源;)

153 double AIShell::heuristic(int ** board)
154 {
155     pthread_t new_threads[3] = {0};
156     pthread_attr_t attr;
157     int th;
158     long t;
159     struct start_end * se;
160     se = (struct start_end *) malloc(3*sizeof(struct start_end));
161
162     pthread_attr_init(&attr);
163     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
164
165     for (int i = 0; i <3; i ++)
166     {
167         (se+i)->board = copy(board);
168         (se+i)->start_row = numRows/4*i;
169         (se+i)->end_row = numRows/4*(i+1);
170         (se+i)->start_col = numCols/4*i;
171         (se+i)->end_col = numCols/4*(i+1);
172         (se+i)->total = 0;
173         th = pthread_create(&new_threads[i], &attr, (void * (*)(void *)) &AIShell::thread_work, (void *) (se+i));
174         if (th)
175         {
176             perror("pthread_create");
177             exit(1);
178         }
179     }
180
181
182     int start_row = numRows/4*3;
183     int end_row = numRows;
184     int start_col = numCols/4*3;
185     int end_col = numCols;
186     int total = 0;
187
188     for (int row = start_row; row != end_row; row++)
189     {
190         for (int col = start_col; col != end_col; col++)
191         {
192             total += check8(board, col, row);
193         }
194     }
195
196     for (int i = 0; i != 3; i++)
197     {
198         th = pthread_join(new_threads[i], (void **) (se+i));
199         if (th)
200         {
201             perror("pthread_join");
202             exit(1);
203         }
204     }
205
206     for (int i = 0; i != 3; i++)
207     {
208         total += (se+i)->total;
209         free((se+i));
210     }
211
212     pthread_attr_destroy(&attr);
213
214     free(se);
215
216     return total;
217 }

我意识到这样做是非常&#34; C&#34;我和我可以用#34; new&#34;或者其他什么,但正如我所说,我改编了来自&#34; C&#34;在这个&#34; C ++&#34;中使用的项目项目,并希望这样做而不必重写所有内容。我也不是肯定的我正在释放&#34;正确的,但它还没有在我的代码中到达那里,所以这更像是次要问题。所以尽管如此,有没有人看到我在这里做错了什么?我尝试了很多东西,似乎无法让它发挥作用:/

0 个答案:

没有答案