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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.83
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
#1

Написать программу, создающую два потока, которые выполняются в одном адресном пространстве (в одном процессе) - C++

17.12.2011, 21:19. Просмотров 2651. Ответов 25
Метки нет (Все метки)

Здравствуйте!
Есть задание: Написать программу, создающую два потока, которые выполняются в одном адресном пространстве (в одном процессе). Их разделяемый ресурс - целочисленный массив, который содержит данные совместного использования. Потоки должны обрабатывать массив поочередно. Использовать критическую секцию для синхронизации. Пример обработки массива: нахождение суммы всех элементов, вывод этой суммы на экран и запись её в первый элемент массива.

Есть код:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <windows.h>
#include <stdio.h>
 
CRITICAL_SECTION cs = {0};
int a[]= {1,2,3};
 
 
DWORD WINAPI SUM(LPVOID param)
{
    int i=0;
    int sum;
    while(TRUE)
    {
        EnterCriticalSection(&cs);
        sum = 0;
        for(i=0; i<3; i++)
        {
            sum=sum+a[i];
        }
        a[0]=sum;
       
        LeaveCriticalSection(&cs);
        if (a[0] > 100) return 0;
    }
    return 0;
}
DWORD WINAPI PRINT(LPVOID param)
{
    while (TRUE)
    {
        EnterCriticalSection(&cs);
        printf("%d %d %d \n",a[0],a[1],a[2]);
        LeaveCriticalSection(&cs);
        if (a[0] > 100) return 0;
    }
    return 0;
}
 
int main(void)
{
    HANDLE THR[1];
 
    InitializeCriticalSection(&cs);
 
    THR[0]=CreateThread(NULL, 0, PRINT, NULL , 0, NULL);
    THR[1]=CreateThread(NULL, 0, SUM, NULL, 0, NULL);
 
    WaitForMultipleObjects(2, THR, TRUE, INFINITE);
 
    CloseHandle(THR[0]);
    CloseHandle(THR[1]);
    DeleteCriticalSection(&cs);
 
    getchar();
    return 0;
}
Желаемо, чтобы в итоге выводил нечто вроде:
6 2 3
11 2 3
16 2 3
.........
101 2 3,
а вместо этого:
101 2 3.
Пожалуйста помогите разобраться. Заранее спасибо!

Добавлено через 20 часов 0 минут
Господа, пожалуйста, помощь нужна!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2011, 21:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Написать программу, создающую два потока, которые выполняются в одном адресном пространстве (в одном процессе) (C++):

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

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

Найти минимальный элемент и все элементы, расположение в одном ряду и в одном столбце с минимальным - C++
Дана квадратная матрица A порядка n. Составить программу, которая находит минимальный элемент и все элементы, расположение в одном ряду и в...

Написать программу, содержащую два потока, каждый из которых управляет движением одного из двух шаров - C++
Написать программу, содержащую два потока, каждый из которых управляет движением одного из двух шаров. Первый шар двигается горизонтально,...

Два значения в одном элементе списка - C++
Подскажите как в сделать односвязный список, чтобы при добавление элемента добавлялись два значения?

LNK2019 два проекта в одном решении (MSVC gtest) - C++
Собственно собрал gtest 1.7.0 static debug с ключом /MTd. Создал решение. Добавил в него проект, в котором есть функтор class...

25
lavan
53 / 53 / 1
Регистрация: 21.03.2009
Сообщений: 371
18.12.2011, 13:48 #16
а что конкретно не то?
0
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
18.12.2011, 13:52 #17
ну если заниматься буквоедством - то вы задание выполнили. потоки делают то, что вам нужно. потом, нигде в задании не сказано, что один поток занимается печатью, а другой подсчетом суммы. вы можете написать ф-ию, которая суммирует и сразу же печатае. т.е. две задачи в одном потоке. создайте два потока и передайте им эту ф-ию. и это тоже будет соответствовать заданию, если под обработкой массива понимать именно набор действий.
0
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
18.12.2011, 13:53  [ТС] #18
Вот используя семафоры все вышло просто чудесно!
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <windows.h>
#include <stdio.h>
 
 
CRITICAL_SECTION cs = {0};
int a[]= {1,2,3};
int sem = 0;
 
 
DWORD WINAPI SUM(LPVOID param)
{
    int i=0;
    int sum;
    while(TRUE)
    {
        while (sem == 0);
        sem = 1;
    EnterCriticalSection(&cs);
    putchar('\r');
    sum = 0;
    for(i=0; i<3; i++)
        {
        sum=sum+a[i];
        }
    a[0]=sum;
    LeaveCriticalSection(&cs);
    sem = 0;
    if (a[0] > 100) return 0;
    }
    return 0;
}
DWORD WINAPI PRINT(LPVOID param)
{
    while (TRUE) {
    while (sem == 1);
    sem = 0;
    EnterCriticalSection(&cs);
    printf("%d %d %d \n",a[0],a[1],a[2]);
    LeaveCriticalSection(&cs);
    sem = 1;
    if (a[0] > 100) return 0;
    }
    return 0;
}
 
int main(void)
{
    HANDLE THR[1];
    InitializeCriticalSection(&cs);
    THR[0]=CreateThread(NULL, 0, SUM, NULL, 0, NULL);
    THR[1]=CreateThread(NULL, 0, PRINT, NULL , 0, NULL);
    WaitForMultipleObjects(2, THR, TRUE, INFINITE);
    CloseHandle(THR[0]);
    CloseHandle(THR[1]);
    DeleteCriticalSection(&cs);
    puts("End threads.");
    getchar();
    return 0;
}
http://imglink.ru/pictures/18-12-11/...d79808cb79.jpg
0
lavan
53 / 53 / 1
Регистрация: 21.03.2009
Сообщений: 371
18.12.2011, 14:08 #19
Цитата Сообщение от final_sleep Посмотреть сообщение
1-й поток суммирует
2-й поток выводит
1-й поток суммирует
2-й поток выводит
ну вот такое что-то.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while(true) {
    EnterCriticalSection(&cs);
        for(int i=0;i<5;i++)
        ar[0]+=ar[i];
    LeaveCriticalSection(&cs);
        if(ar[0]>100)break;
        Sleep(50);//передали управление в поток показа
.....................
Sleep(50);//дали возможность взять управление потоку суммирования
    while(true) {
        EnterCriticalSection(&cs);
        for(int i=0;i<5;i++)
        cout<<ar[i]<<" ";//вывели результат
        cout<<endl;
        LeaveCriticalSection(&cs);
        if(ar[0]>100)break;
        Sleep(50);//для однозначности передачи управления в поток суммирования
    }
    }
Добавлено через 13 минут
Несколько слов о вышем коде.
1)Вы не используете семафоры!
2)У вас присутствует банальный выход за пределы массива
C++
1
2
3
HANDLE THR[1];
        THR[0]=CreateThread(NULL, 0, SUM, NULL, 0, NULL);
    THR[1]=CreateThread(NULL, 0, PRINT, NULL , 0, NULL);
0
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
18.12.2011, 14:20  [ТС] #20
lavan, выход почему-то никак не сказался О_О
Эм эт блокирующая переменная. Извините, каша в голове.

Добавлено через 4 минуты
и к тому же в вашем алгоритме
C++
1
a[0]+=a[i]
сумма элементов должна не прибавляться, а записываться в первый элемент.
0
lavan
53 / 53 / 1
Регистрация: 21.03.2009
Сообщений: 371
18.12.2011, 14:28 #21
В моем коде я вам показал логику работы с критическими секциями для вашего случая,а изменить алгоритм суммирования думаю не должно быть проблемой! Семафор-это объект синхронизации а не блокирующая переменная.
C++
1
2
3
4
...
sum+=ar[i];
..
ar[0]=sum;
1
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
18.12.2011, 14:42  [ТС] #22
lavan, спасибо,все работает!)

Добавлено через 5 минут
но есть почему то, он пропускает первые несколько шагов в принте
как это перебороть?
Для массива:
C++
1
int ar[]={2,5,7,9,3};
Вот такое получил (
http://imglink.ru/pictures/18-12-11/...52f991f7bb.jpg

Добавлено через 1 минуту
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
29
30
31
32
33
34
35
36
37
38
39
#include<windows.h>
#include<iostream>
using namespace std;
CRITICAL_SECTION cs;
int ar[]={2,5,7,9,3};
int coutn;
void thr();
int main() {
        HANDLE htr;
        DWORD dwId;
        InitializeCriticalSection(&cs);
        htr=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thr,NULL,0,&dwId);
        Sleep(70);
        while(true) {
                EnterCriticalSection(&cs);
                for(int i=0;i<5;i++)
                cout<<ar[i]<<" ";
                cout<<endl;
                LeaveCriticalSection(&cs);
                       if(ar[0]>300)break;
                Sleep(70);
        }
         CloseHandle(htr);
         DeleteCriticalSection(&cs);
        cin.get();
        return 0;
}
void thr() {
        while(true) {
        int sum=0;
            EnterCriticalSection(&cs);
                for(int i=0;i<5;i++)
                sum+=ar[i];
                ar[0]=sum;
        LeaveCriticalSection(&cs);
                if(ar[0]>300)break;
                Sleep(70);
    }
}
0
lavan
53 / 53 / 1
Регистрация: 21.03.2009
Сообщений: 371
18.12.2011, 19:56 #23
я думаю,что это происходит из-за этой проверки

Цитата Сообщение от final_sleep Посмотреть сообщение
if(ar[0]>300)break;
Sleep(70);
здесь возможно происходит следущее:1-й поток вышел из критич секции 2-ой поток сразу зашел в крит секцию и после того как он ее освободил мы ожидаем что первый поток стоит в while,а он находится на проверочном условии,за время проверки условия в первом потоке истекает sleep во втором потоке а первый поток вызывает свой sleep и второй поток сново входит в крит секцию.я бы перенес условие выхода в while(условие)
1
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
18.12.2011, 20:42  [ТС] #24
проблема увы осталась ( иногда пропускает первые два вывода суммы, то есть:
26 5 7 9 3
74 5 7 9 3
97 5 7 9 3
122 5 7 9 3
170 5 7 9 3
стабильно хоть где то да пропустит
может увеличить sleep?


увеличение sleep, не очень помогло, думается мне надо блокирующую переменную ввести и дел с концом.

Ввел переменную - все как надо, может действительно не заниматься буквоедством? Критическую секцию использовали? - Использовали!
0
lavan
53 / 53 / 1
Регистрация: 21.03.2009
Сообщений: 371
18.12.2011, 20:55 #25
решать вам,но может стоит проверочное условие внести в секцию и если усовие выполняется освобождать кр секцию и брик
1
final_sleep
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 19
19.12.2011, 00:56  [ТС] #26
попробовал. не получилось. остановился на семафорах!
0
19.12.2011, 00:56
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2011, 00:56
Привет! Вот еще темы с ответами:

Два класса в одном заголовочном файле, предварительное объявление - C++
Дико туплю, никак не могу понять, где косячу. Ситуация - есть два описания классов в одном заголовочном файле (все делается с...

Вывести строку в два столбца: в одном строчные буквы, во втором прописные - C++
помогите нубу написать программу) Вводные данные: 20 букв Представление выводных данных: два столбца: в одном строчные, во втором...

Даны 3 массива. Выдать элементы, которые встречаются только в одном из них - C++
Даны 3 массива. Выдать элементы, которые встречаются только в одном из них.

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


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

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

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