我正在开发一个个人项目,用随机数填充数组,使用pthread(POSIX)拆分为多个用户定义的段,在每个段中搜索目标,并返回目标的次数找到。我有错误和问题。对于多个线程,问题包括目标没有保存在struct成员中,而是一个未创建的线程和其他事情发生。我确定我的逻辑是关闭的,我的代码和它的输出反映了这一点,但我很难过。你如何将数组拆分成线程?我弄乱了什么逻辑?
HEADER FILE ...
#ifndef COUNT_ARRAY_H
#define COUNT_ARRAY_H
// structure declarations
typedef struct
{
int threadNum;
int *array;
int first;
int last;
int target;
int numFound;
} ThreadInfo;
// function prototypes
void* ThreadFunc(void *vptr);
#endif // COUNT_ARRAY_H
主要文件....
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "count_array.h"
int main(void)
{
int numSegs;
int numSegElems;
int maxRand;
int target;
int totalElems;
int totalFound = 0;
ThreadInfo *infoPtr;
pthread_t *threadHandles;
int index = 0;
int first;
int last;
int threadNum = 0;
//get primary info from user...
printf(" Please enter the total number of elements? ");
scanf("%d", &totalElems);
printf(" Please enter the maximum random value: ");
scanf("%d", &maxRand);
printf(" Please enter the number of segments (1 to 15857): ");
scanf("%d", &numSegs);
if(numSegs > 15857)
{
puts(" Too many segments for machine!");
exit(EXIT_FAILURE);
}
numSegElems = totalElems/numSegs;
// configure the array to work with
// declare array here...
int myArray[totalElems];
//and fill array here
for(; index < totalElems; index++)
{
// % rand() and maxRand to get good range and
//not go beyond users max number
myArray[index] = (rand() % maxRand);
//test printf...ignore if still here
printf(" %d \n", myArray[index]);
}
// get the target value to look for
printf(" Please enter the target value: ");
scanf("%d",&target);
// display initial information
printf("*** Begin search: target = %d, # elements = %d, # segments = %d, "
"# segment elements = %d\n"
, target
, totalElems
, numSegs
, numSegElems);
// initialize the array first/last indexes into the integer array
if(numSegs == 1)
{
first = totalElems;
last = 0;
}
else
{
first = totalElems - numSegElems;
last = (first - numSegElems);
}
// allocate an array to store the thread handles
int size; //size of segment
if(numSegs > 1)
{
size = numSegElems;
}
else
{
size = totalElems;
}
//test printf...please ignore if still here
//printf(" size %d \n", size);
int segA[size];//not sure if I need this
// loop and create threads (# of segments)
index = 0;
for(; threadNum < numSegs; index++)
{
// allocate a thread info structure from the heap
threadHandles = calloc(totalElems, sizeof(pthread_t));
infoPtr = calloc(totalElems, sizeof(ThreadInfo));
// store the information in the allocated structure
infoPtr[index].threadNum = threadNum;
infoPtr->target = target;
infoPtr->first = first;
infoPtr->last = last;
infoPtr->array = myArray;
// create the secondary thread, passing the thread info
pthread_create(&threadHandles[index], NULL, ThreadFunc, &infoPtr[index]);
// update the first/last array indexes for the next thread
first = last;
last = first-numSegs;
++threadNum;
}
// loop and join the threads to fetch each thread's results
for(index = 0; index < numSegs; index++)
{
// join with the next thread
pthread_join(threadHandles[index], NULL);
// get the total number of matches from the thread's infoPtr
// and display a message
printf(" *** pthread_join returned: threadNum = %d, numFound = %d\n",
infoPtr[index].threadNum, infoPtr->numFound);
}
// release the infoPtr structure back to the heap
free(infoPtr);
// display the final results
// release heap memory
free(threadHandles);
return 0;
} // end of "main"
void* ThreadFunc(void *vptr)
{
//declare and set vars
ThreadInfo *ptr = vptr;
ptr->numFound = 0;
int index = ptr->first-1;
//test printf...ignore if still here
printf(" Targ %d \n", ptr->target);
//start search
for(; index >= ptr->last; --index)
{
printf(" %d \n", ptr->array[index]);
//if target found
if(ptr->target == ptr->array[index])
{
puts(" Target found! ");
//increment numFound
++ptr->numFound;
}
}
//drop out and display message
}
答案 0 :(得分:1)
您在threadHandles
和infoPtr
的分配中遇到了多个错误。首先,您真的不想分配totalElems
个 - 只需要numSegs
。其次,更重要的是,每次通过线程调用循环时,您都要重新分配它们并更改指针infoPtr
和threadHandles
的值。第三,你在这里混合处理infoPtr
作为一组ThreadInfo
结构:
infoPtr[index].threadNum = threadNum;
将其视为指向不断变化的ThreadInfo
结构的指针:
infoPtr->target = target;
infoPtr->first = first;
infoPtr->last = last;
infoPtr->array = myArray;
所以每次循环时,你只在第一个线程上设置这些参数。
要解决此问题,请在循环之前编辑并移动分配,并将infoPtr
始终视为数组:
threadHandles = calloc(numSegs, sizeof(pthread_t));
infoPtr = calloc(numSegs, sizeof(ThreadInfo));
for(; threadNum < numSegs; index++)
{
infoPtr[index].threadNum = threadNum;
infoPtr[index].target = target;
infoPtr[index].first = first;
infoPtr[index].last = last;
infoPtr[index].array = myArray;
并进一步确定infoPtr
中printf
的第二次使用:
printf(" *** pthread_join returned: threadNum = %d, numFound = %d\n",
infoPtr[index].threadNum, infoPtr[index].numFound);
事情会好一点。
first
和last
的设置中仍有更多错误。我建议你打印出他们的价值观,并确保他们以你想要的方式出现。我很容易让他们变得消极(并开始搜索随机记忆)。