使用 pthread 分割和搜索数组段的问题
Posted
技术标签:
【中文标题】使用 pthread 分割和搜索数组段的问题【英文标题】:Problems splitting and searching array segments with pthreads 【发布时间】:2017-05-15 23:06:06 【问题描述】:我正在做一个个人项目,用随机数填充数组,使用 pthread (POSIX) 拆分为多个用户定义的段,在每个段中搜索目标,并返回目标的次数成立。我有错误和问题。对于多个线程,诸如目标未保存在结构成员中和未创建线程等问题会发生。我确定我的逻辑是关闭的,我的代码和它的输出反映了这一点,但我很难过。如何将数组拆分为线程?我在搞砸什么逻辑?
头文件...
#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
【问题讨论】:
你没有pthread_create
和pthread_join
的头文件
【参考方案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;
并在此printf
中将infoPtr
的第二次使用更进一步:
printf(" *** pthread_join returned: threadNum = %d, numFound = %d\n",
infoPtr[index].threadNum, infoPtr[index].numFound);
事情会变得更好。
在您的first
和last
设置中还有更多的错误挥之不去。我建议您打印出它们的值,并确保它们以您想要的方式出现。我能够很容易地让它们变得消极(并开始搜索随机记忆)。
【讨论】:
我现在明白了。我能够解决第一个和最后一个问题,但是 pthread 存在问题。 for 循环将启动,打印出第一个和最后一个(这样我每次都能看到里面的内容),然后不创建线程。它只是跳过 pthread_create 并回到顶部。我不知道为什么会发生这种情况。我应该尝试在 for 循环的底部还是顶部添加分配内容? 其实我想通了。我没有增加我的索引等。感谢您的帮助!以上是关于使用 pthread 分割和搜索数组段的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?