Как я могу инициировать массив, каждый элемент в отдельном потоке - PullRequest
0 голосов
/ 10 ноября 2011

Я пытаюсь создать массив размером n (где n - ввод пользователя), и когда пользователь запускает программу, элементы массива должны быть установлены в 1 (каждый в отдельном потоке). Вот что я сделал до сих пор:

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>

int *x;

DWORD WINAPI init_X(LPVOID param)
{
    int index = *(int *) param;
    x[index] = 1;

    return 0;
}

int main(int argc, char *argv[])
{
    int n = atoi(argv[1]);
    int i; // counter.
    HANDLE THandles[n];

    x = malloc(n * sizeof (int));

    for(i = 0; i < n; i++)
    {
        THandles[i] = CreateThread(NULL, 0, init_X, &i, 0, NULL);
    }

    // Now wait for threads to finish
    WaitForMultipleObjects(n, THandles, TRUE, INFINITE);

    // Close the thread handle
    for(i = 0; i < n; i++)
    {
        CloseHandle(THandles[i]);
    }

    printf("After initialization x = ");
    for(i = 0; i < n; i++)
    {
        printf("%d ", x[i]);
        if(i < n - 1) printf(" ");
    }

    // ...

    return 0;
}

Я запустил эту программу и получил неправильные результаты:

> Test.exe 3
After initialization x = 11611536 11600064 50397186

Это должно быть After initialization x = 1 1 1 хотя. Я не уверен, как я могу это исправить, но я уверен, что это что-то связано с указателями.

P.S .: Я программист на Java, поэтому я не знаком с указателями.

Ответы [ 2 ]

2 голосов
/ 10 ноября 2011

Значение, которое вы передаете в качестве индекса массива, скорее всего, будет недействительным ко времени выполнения потока, поскольку нет гарантии, что поток будет запущен сразу после вызова CreateThread.

У вас есть два решения: либо передать по значению (просто и легко, но не всегда безопасно), либо выделить временный буфер для значения, которое будет освобождено потоком при его использовании.

Незначительное обновление:

На самом деле, лучший способ - передать &x[i], тогда вы можете просто сделать *(int*)param = 1;

0 голосов
/ 10 ноября 2011

Вы передаете i по указателю на поток, поэтому значение, которое получает каждый поток, будет зависеть от того, когда на самом деле выполняется int index = *(int *) param;, и должно быть что-то между 0 и n. Вы можете просто передать i по значению (приведенному к указателю), чтобы избежать этого.

...