Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
#1

Реализация работы с массивом только в одном потоке - C++

01.05.2012, 15:37. Просмотров 597. Ответов 3
Метки нет (Все метки)

Доброго времени суток!
Пытаюсь реализовать программу, в которой будет 2 потока, в оба передается массив, один поток инкрементирует, другой декрементирует.
Пока конечная цель сделать так, что бы в один момент времени с массивом работал только один поток и не прерывался, пока не закончит обработку, разумеется использование глобальной переменной не вариант.
Сейчас все работает так: запускается поток инкрементирования, обрабатывает массив (может даже несколько раз), после - запускается поток декрементирования и все ломается при попытке работы с массивом.
Но я работаю с копией массива (потом хочу придумать способ возврата значения в main)! ..во всяком случае задумка была работать с копией..
Вопрос заключается в том, почему возникает ошибка и как её устранить.
Так же приведу куски программы.
C++
1
2
3
4
5
6
7
8
9
10
11
DWORD WINAPI Thread_1(LPVOID pParam) //функция потока, второй поток почти идентичен
{
    DWORD dwResult=0;
    int *array; //  будущая !!!копия!!! массива
    array=new int[20]; 
    array=((int*)pParam); 
    cout<<"its work 1 !";
        for(int i=0;i<20;i++) {array[i]++; cout<<array[i];} //работа с массивом
    return dwResult; 
}
CreateThread(NULL,NULL,&Thread_1,(LPVOID)array,0,0); //создание потока1 в main
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2012, 15:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Реализация работы с массивом только в одном потоке (C++):

Переделать программу работы с массивом для работы с вектором - C++
помогите переделать эту программу!!...при одном условии....вот что находится между int main() и return 0; сохранить.....здесь нужно...

Напечатать только те символы, которые встречаются только в одном из слов - C++
Даны два слова, напечатать только те символы, которые встречаются только в одном из слов. Например, для слов процессор и информация....

Даны два слова, напечатать только те символы, которые встречаются только в одном из слов - C++
помогите, пожалуйста, с программой:) Писать ее не нужно, просто нужно помочь объяснить как ее сделать) я не могу понять алгоритм действий....

Даны два слова. Напечатать только те буквы слов, которые есть только в одном из них - C++
2.Даны два слова. Напечатать только те буквы слов, которые есть только в одном из них (в том числе повторяющиеся). Например, если ...

Реализация стека массивом - C++
При реализации стека массивом обеспечить размещение двух стеков в одном массиве. Один стек размещается в начале массива и растет до конца,...

Реализация очереди массивом - C++
Как реализовать очередь с помощью массива????

3
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
01.05.2012, 15:42  [ТС] #2
И приведу еще скрин моей ошибки
0
Миниатюры
Реализация работы с массивом только в одном потоке  
andy_111
90 / 59 / 2
Регистрация: 03.07.2011
Сообщений: 148
01.05.2012, 15:53 #3
Для обеспечения синхронизации работы нескольких потоков в винде существует ряд встроенных механизмов...например критические секции.
По Вашей программе - вы сначала выделяете память под массив, строка 5. Потом этому же указателю присваиваете значение указателя из параметра, разумеется теряя указатель на только что выделенную память. Уже это странно как-то. А поток создаете, передавая ему параметром какой-то array, непонятно как объявленный и проинициализированный...
А почему использование глобальной переменной "не вариант"? У вас есть переменная - массив, видимая по указателю в обоих потоках. Вы к этой переменной в них поочередно обращаетесь, а регулируете обращение через критические секции.
И поток у вас странный какой-то В текущем его исполнении толку от него ноль, по моему - настолько быстро он проскочит.
0
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
01.05.2012, 19:15  [ТС] #4
По Вашей программе - вы сначала выделяете память под массив, строка 5. Потом этому же указателю присваиваете значение указателя из параметра, разумеется теряя указатель на только что выделенную память. Уже это странно как-то.
Не совсем понял что не так. Что бы воспользоваться параметром потока, пришлось немного помучатся, поскольку с первого раза не вышло. Во всяком случае именно в таком варианте, мне удалось передать массив, а не просто переменную.
А почему использование глобальной переменной "не вариант"?
Привык что за это "ругают", просто привык обходится без них, хотя согласен что это наиболее легкий вариант, если бы мне просто нужно было сделать хоть как-то
А поток создаете, передавая ему параметром какой-то array, непонятно как объявленный и проинициализированный...
Инициализация и обявление в мейне:
C++
1
2
    int *array=new int[20];
    for(int i=0;i<20;i++) array[i]=0;
В текущем его исполнении толку от него ноль, по моему - настолько быстро он проскочит
Не все учебные задачи имеют практический смысл

Добавлено через 23 минуты
Нашел ошибочку! Это была очень глупая опечатка во втором потоке, сейчас буду думать над синхронизацией

Добавлено через 2 часа 40 минут
Странно, в несколько модифицированном варианте функции потока оно работает как надо, но только в 9 из 10 запусках и я не могу никак понять почему:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
DWORD WINAPI Thread_1(LPVOID pParam)
{
    DWORD dwResult=0;
    int *array=new int[20]; 
    array=((int*)pParam); //я проверил, моя задумка работать с копией была несколько неверно реализованна, но это к лучшему - при работе с массивом в потоке, меняется и оригинал
    //cout<<"its work 1 !";
    for(int j=0;j<9;j++) 
    {
        while(flag!=0) //глобальный флаг потока (0- первый поток, 1-второй поток, 3-поток завершил работу)
        {
            Sleep(1); //ничего не делаем
            if (flag==3) //если можно, то делаем первый поток текущим и начинаем работать
            {
                flag=0;
            }
        }
        for(int i=0;i<20;i++) 
        {
            array[i]++; //инкрементируем массив (в потоке2 - декрементируем)
            cout<<array[i];
        }
        flag=3; //устанавливаем флаг возможности выбора начала работы другого потока
    
    }
 
    flag0=1; 
    return dwResult; 
}
Добавлено через 3 минуты
и почему-то в текущем варианте, в конце всегда массив нулевой, я объясняю это тем, что обоим потокам предоставляется одинаковое количество процессорного времени, я прав?
0
01.05.2012, 19:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.05.2012, 19:15
Привет! Вот еще темы с ответами:

Реализация класса с динамическим массивом в качестве поля - C++
Доброго времени суток. Суть задания: нужно реализовать класс, у которого в качестве поля будет динамический массив. У меня в данном коде в...

Структура для работы с массивом - C++
напишите пожалуйста программу по следующему заданию.. очень нужно.. Создать структуру для работы с массивом. Данные структуры: массив...

Функция работы с двумерным массивом - C++
Не могу вызвать функцию в основной программе. В задании перед массивом двумерным вообще требуется поставить 1 указатель,но так тоже не...

Класс для работы с трёхмерным массивом - C++
Программа должна демонстрировать работу с классом объявленным и определённым, класс применяется для работы с трёхмерным массивом . Он...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru