Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Win32 API上将结构传递给线程时出现指针问题_C_Multithreading_Winapi_Pointers_Struct - Fatal编程技术网

C 在Win32 API上将结构传递给线程时出现指针问题

C 在Win32 API上将结构传递给线程时出现指针问题,c,multithreading,winapi,pointers,struct,C,Multithreading,Winapi,Pointers,Struct,用户提供用于计算分区数和线程数的命令行参数,其中每个线程对大型数组的特定分区进行最小线性搜索。线程找到的每个最小值都存储在一个小型全局数组中。然后,主函数对小数组进行最小线性搜索,同时对大数组进行最小搜索,并确认在小数组和大数组中找到的最小值相等。我遇到的问题是,小全局数组中的最小值有时是垃圾,有时与大数组中的最小值匹配。我试图找出这个问题,但似乎找不到。我们将非常感谢你的帮助。我正在用C编写代码,在win32 API上使用Dev-C++。代码如下: #include <inttypes.

用户提供用于计算分区数和线程数的命令行参数,其中每个线程对大型数组的特定分区进行最小线性搜索。线程找到的每个最小值都存储在一个小型全局数组中。然后,主函数对小数组进行最小线性搜索,同时对大数组进行最小搜索,并确认在小数组和大数组中找到的最小值相等。我遇到的问题是,小全局数组中的最小值有时是垃圾,有时与大数组中的最小值匹配。我试图找出这个问题,但似乎找不到。我们将非常感谢你的帮助。我正在用C编写代码,在win32 API上使用Dev-C++。代码如下:

#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define RAND_DIVISOR 800

int number_items = 0;
int size = 1;
int partits = 1;
int P = 0;
int N = 0;
int Index = 0;
int index_global = 0;
int min;


#define NUM_THREADS 65536  //or 2^16


typedef struct thread_data
{
int thread_id;
int a;
int b;
int * copy_array;
int * glob_array;
int nbr_items; 
int subarraysize;

} s_param, *p_s_param;


int compare (const void *a, const void *b)
{
return( *(int*)a - *(int*)b);

}


DWORD WINAPI CompMin( LPVOID lpParam )
{
    int i, tmp;
int SubArSize,nbrItems,thrid;
    p_s_param param2;
param2 = (p_s_param)lpParam;


min = param2->copy_array[Index];
min = param2->copy_array[param2->a];
param2->glob_array[index_global] = min; 
Index++;
index_global++;

    }


int main(int argc, char *argv[])
{ 
    int sub_array_size;


p_s_param pDataArray[NUM_THREADS];
DWORD dwThreadIdArray[NUM_THREADS];
    HANDLE hThreadArray[NUM_THREADS]; 
HANDLE myhandle;
//pthread_t thID, thread;   

    p_s_param param[NUM_THREADS];
    int rNum, rc = 0, i, j, large_min;


    double time1, time2, time3, time4;

    //get initial timestamp in micro seconds
    struct timeval tv;
    gettimeofday( &tv, NULL );
    time1 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );
    printf( "Start timestamp: %f\n", time1 );


    if(argc < 2 )
    {
        printf("Need %d arguments, only %d provided\n", 2, argc);
        printf("The program will exit now!\n");
        return 1;
    }

P = atoi(argv[1]); /* will be used to define size of large array */ 
N = atoi(argv[2]); /* will be used to define number of threads */ 

    if(N>P)
    {
    printf(" Argument 1 should be greater than argument 2\n");
        printf("The program will exit now!\n");
        return 1;
    }

/*compute the size of the array*/
for (i=1; i<=P; i++)
    size = size * 2;

/*Create a dynamic array of size size*/
int *array = (int*) malloc(size*sizeof(int));

srand(time(NULL));

for (i=0; i<size; i++) 
{
        rNum = rand() / RAND_DIVISOR;
    array[i] = rNum;

}

/*compute the number of partitions*/
for (i = 1; i<=N; i++)
    partits = partits * 2;

/*numbers of elements per sub array*/
sub_array_size = size/partits;

/*Global array*/
int *Globalarray = (int*) malloc(partits*sizeof(int));


    for (i=0; i<partits; i++)
    {

    /*Allocate memory for thread data*/
         param[i] = (p_s_param) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(s_param));

    if( param[i] == NULL)
    {
    ExitProcess(2);
    }

    param[i]->a=i;

    param[i]->copy_array=array;

    param[i]->glob_array = Globalarray;

hThreadArray[i] = CreateThread(NULL, 0, CompMin, param[i], 0, &dwThreadIdArray[i]);

    if(hThreadArray[i] == NULL)
    {
    puts("Error, cannot create Thread!");
    puts(strerror(errno));
    ExitProcess(3);

    }


    //printf("Number of partitions: %d\n",partits );    
}    WaitForMultipleObjects(NUM_THREADS,hThreadArray, TRUE, INFINITE);



    /*find mimimum value from Global array returned by threads*/
    min = Globalarray[0];
    for(i = 0; i< partits; i++)
    {   
        printf("Index: %d, value into small array: %d\n",i, Globalarray[i] );   
    if(Globalarray[i] < min)
        min = Globalarray[i];
    }


    gettimeofday( &tv, NULL );
    time2 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );


    gettimeofday( &tv, NULL );
    time3 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );

    /*sorting the large array in ascending order and find minimum value*/
    //qsort(array,size, sizeof(int), compare);
    large_min = array[0];
    for(i = 0; i< partits; i++)
    {
        printf("value into large array: %d\n",array[i] );   
    if(array[i] < large_min)
            large_min = array[i];
    }
    //large_min = array[0];

    gettimeofday( &tv, NULL );
    time4 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );

    /*display result*/
    printf("Min from small array : %d\n", min);
    printf("Min from large array : %d\n", large_min);
    if(min == large_min)
    printf("Same minimum found in small and large array! : %d\n", large_min);

    else
    {   
        printf("error!, the min from small %d array is different from large array %d!\n", min, array[0]);

        return 1;
    }
    printf("length of time recorded to search min in small array: %f\n", time2-time1);

    printf("length of time recorded to search min in large array: %f\n", time4-time3);


    free((void*) Globalarray);
    free((void*) array); 


exit (0);

} 
#包括
#包括
#包括
#包括
#包括
#定义RAND_除数800
整数项=0;
int size=1;
int partits=1;
int P=0;
int N=0;
int指数=0;
int index_global=0;
int-min;
#定义NUM_线程65536//或2^16
typedef结构线程数据
{
int-thread_-id;
INTA;
int b;
int*copy_数组;
int*glob_数组;
国际nbr_项目;
int子阵列大小;
}s_参数,*p_s_参数;
整数比较(常数无效*a,常数无效*b)
{
返回(*(int*)a-*(int*)b);
}
DWORD WINAPI CompMin(LPVOID lpParam)
{
int i,tmp;
整数子大小,NBR项,三次;
p_s_param param2;
param2=(p_s_param)lpParam;
min=param2->复制数组[索引];
min=param2->copy_数组[param2->a];
参数2->全局数组[索引全局]=min;
索引++;
索引_global++;
}
int main(int argc,char*argv[])
{ 
int子数组大小;
p_s_参数pDataArray[NUM_THREADS];
DWORD DWTHREADIRAY[NUM_THREADS];
句柄hThreadArray[NUM_THREADS];
把手我的把手;
//pthread_t thID,thread;
p_s_param param[NUM_THREADS];
int rNum,rc=0,i,j,大_min;
双时间1,时间2,时间3,时间4;
//以微秒为单位获取初始时间戳
结构时间值电视;
gettimeofday(&tv,NULL);
time1=tv.tv\u sec+(tv.tv\u usec/1000000.0);
printf(“开始时间戳:%f\n”,time1);
如果(argc<2)
{
printf(“需要%d个参数,只提供了%d个”,2,argc);
printf(“程序将立即退出!\n”);
返回1;
}
P=atoi(argv[1]);/*将用于定义大数组的大小*/
N=atoi(argv[2]);/*将用于定义线程数*/
如果(N>P)
{
printf(“参数1应大于参数2\n”);
printf(“程序将立即退出!\n”);
返回1;
}
/*计算数组的大小*/
对于(i=1;i我在等待后添加了睡眠(3),它解决了问题。

您的
CompMin()
函数不是线程安全的。它正在访问由多个线程同时共享和修改的全局变量,因此当它们彼此并行运行时,它们将跨过彼此的数据。您需要使您的工作数据自包含,以便每个线程仅对其指定工作的数据进行操作,并且您设计的
thread\u data
struct允许对数组数据进行分区,但实际上并没有利用该功能,因此每个线程都没有搜索其单独的数据分区,也没有将其搜索结果存储在全局数组的单独部分

您还将错误数量的线程句柄传递给了
WaitForMultipleObjects()
,因此它将无法等待(您没有检查),然后在数组数据实际准备好处理之前继续处理它们

在线程完成运行后,您也会错误地搜索数组,因此最终不会得到正确的结果

请尝试类似以下内容:

#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define RAND_DIVISOR 800

typedef struct thread_data
{
    DWORD thread_id;
    int *items;
    int nbr_items; 
    int min;

} s_thread_data, *p_s_thread_data;

/*
int compare (const void *a, const void *b)
{
    return( *(int*)a - *(int*)b);
}
*/

DWORD WINAPI CompMin( LPVOID lpParam )
{
    p_s_thread_data data = (p_s_thread_data) lpParam;
    int i;

    data->min = data->items[0];
    for(i = 1; i < data->nbr_items; i++)
    {   
        if(data->items[i] < data->min)
            data->min = data->items[i];
    }

    return 0;
}

int main(int argc, char *argv[])
{ 
    int size = 1;
    int partits = 1;
    int sub_array_size;
    int i;

    if(argc < 2 )
    {
        printf("Need %d arguments, only %d provided\n", 2, argc);
        printf("The program will exit now!\n");
        return 1;
    }

    int P = atoi(argv[1]); /* will be used to define size of large array */ 
    if(P < 1)
    {
        printf(" Argument 1 should be greater than zero\n");
        printf("The program will exit now!\n");
        return 1;
    }

    int N = atoi(argv[2]); /* will be used to define number of threads */ 
    if(N < 1)
    {
        printf(" Argument 2 should be greater than zero\n");
        printf("The program will exit now!\n");
        return 1;
    }

    /*compute the size of the large array*/
    for (i=1; i<=P; i++)
        size = size * 2;

    /*Allocate memory for large array*/
    int *array = (int*) malloc(size*sizeof(int));
    if(array == NULL)
        return 2;

    srand(time(NULL));

    /*Fill the large array with random data*/
    for (i=0; i<size; i++) 
        array[i] = rand() / RAND_DIVISOR;

    /*compute the number of partitions*/
    for (i = 1; i<=N; i++)
        partits = partits * 2;

    //printf("Number of partitions: %d\n", partits );    

    /*numbers of elements per partition*/
    sub_array_size = size/partits;

    /*Allocate memory for thread data*/
    p_s_thread_data ThreadDataArray = (p_s_thread_data) malloc(partits*sizeof(s_thread_data));
    if(ThreadDataArray == NULL)
        return 2;
    memset(ThreadDataArray, 0, partits*sizeof(s_thread_data));

    /*Allocate memory for thread handles array*/
    HANDLE *hThreadArray = (HANDLE*) malloc(partits*sizeof(HANDLE)); 
    if(hThreadArray == NULL)
        return 2;
    memset(hThreadArray, 0, partits*sizeof(HANDLE));

    double time1, time2, time3, time4;

    //get initial timestamp in micro seconds
    struct timeval tv;
    gettimeofday( &tv, NULL );
    time1 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );
    printf( "Start timestamp: %f\n", time1 );

    for (i=0; i<partits; i++)
    {
        ThreadDataArray[i].items = &array[i*sub_array_size];
        ThreadDataArray[1].nbr_items = sub_array_size; 

        hThreadArray[i] = CreateThread(NULL, 0, CompMin, &param[i], 0, &(param[i].thread_id));

        if(hThreadArray[i] == NULL)
        {
            printf("Error, cannot create Thread! %s\n", strerror(errno));
            return 3;
        }
    }

    /*Wait for threads to finish*/
    i = 0;
    int nbr_handles = partits;
    while (nbr_handles >= MAXIMUM_WAIT_OBJECTS)
    {
        if (WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, &hThreadArray[i], TRUE, INFINITE) != WAIT_OBJECT_0)
            return 4;

        i = i + MAXIMUM_WAIT_OBJECTS;
        nbr_handles = nbr_handles - MAXIMUM_WAIT_OBJECTS;
    }
    if (nbr_handles > 0)
    {
        if (WaitForMultipleObjects(nbr_handles, &hThreadArray[i], TRUE, INFINITE) != WAIT_OBJECT_0)
            return 4;
    }

    /*find minimum value from thread results*/
    int min = ThreadDataArray[0].min;
    for(i = 0; i < partits; i++)
    {   
        printf("Index: %d, value into small array: %d\n",i, ThreadDataArray[i].min );   
        if(ThreadDataArray[i].min < min)
            min = ThreadDataArray[i].min;
    }

    gettimeofday( &tv, NULL );
    time2 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );

    gettimeofday( &tv, NULL );
    time3 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );

    /*sorting the large array in ascending order and find minimum value*/
    //qsort(array,size, sizeof(int), compare);
    int large_min = array[0];
    for(i = 0; i < size; i++)
    {
        printf("value into large array: %d\n", array[i] );   
        if(array[i] < large_min)
            large_min = array[i];
    }

    gettimeofday( &tv, NULL );
    time4 = tv.tv_sec + ( tv.tv_usec / 1000000.0 );

    /*display result*/
    printf("Min from small array : %d\n", min);
    printf("Min from large array : %d\n", large_min);
    if(min == large_min)
        printf("Same minimum found in small and large array! : %d\n", large_min);
    else
    {   
        printf("error!, the min from small array (%d) is different from large array (%d)!\n", min, large_min);
        return 1;
    }

    printf("length of time recorded to search min in small array: %f\n", time2-time1);
    printf("length of time recorded to search min in large array: %f\n", time4-time3);

    free(array); 
    free(ThreadDataArray);
    free(hThreadArray);

    return 0;
} 
#包括
#包括
#包括
#包括
#包括
#定义RAND_除数800
typedef结构线程数据
{
德沃德螺纹;
国际*项目;
国际nbr_项目;
int-min;
}s_线程数据,*p_s_线程数据;
/*
整数比较(常数无效*a,常数无效*b)
{
返回(*(int*)a-*(int*)b);
}
*/
DWORD WINAPI CompMin(LPVOID lpParam)
{
p_s_线程数据=(p_s_线程数据)lpParam;
int i;
数据->最小值=数据->项目[0];
对于(i=1;inbr\u项;i++)
{   
if(数据->项目[i]min)
数据->最小值=数据->项目[i];
}
返回0;
}
int main(int argc,char*argv[])
{ 
int size=1;
int partits=1;
int子数组大小;
int i;
如果(argc<2)
{
printf(“需要%d个参数,只提供了%d个”,2,argc);
printf(“程序将立即退出!\n”);
返回1;
}
int P=atoi(argv[1]);/*将用于定义大数组的大小*/
if(P<1)
{
printf(“参数1应大于零\n”);
printf(“程序将立即退出!\n”);
返回1;
}
int N=atoi(argv[2]);/*将用于定义线程数*/
if(N<1)
{
printf(“参数2应大于零\n”);
printf(“程序将立即退出!\n”);
返回1;
}
/*计算大数组的大小*/

对于(i=1;i您可能需要在全局数组上进行某种同步。还要注意,
WaitForMultipleObjects
一次最多只能等待64个句柄,而不是65536个。这个赋值说明我们不需要同步,因为每个线程将在特定分区上搜索最小值。
index\u global
是所有线程共享的全局变量,那么您认为它们将如何避免冲突?我明白您的意思。我如何避免同步,但强制主线程等待每个线程完成?您是否还说在64个句柄之后可能会发生冲突?是否有任何方法将等待设置为65536?我的解决方案是线程的ace索引_全局