Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
0 / 0 / 1
Регистрация: 13.04.2009
Сообщений: 38

Синхронизация потоков

11.05.2010, 00:05. Показов 2850. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Задача состоит в том, чтобы отсортировать слова пользуясь алгоритмом слияния.
Алгоритм реализован правильно, но проблема оказалось в том, что потоки создаются рекурсивно, что усложняет их синхронизацию. Первоначально пробовал синхронизировать мьютексом, но по словам преподавателя тут надо использовать условные переменные. Разобрался и с этой синхронизацией перечитав кучу материала в интернете, однако во всех рассмотрен вариант когда есть поток потребитель и поток производитель. В моем же случае потребитель и производитель это один и тот же поток, поэтому по моему смысл такой синхронизации в моем случае теряется. Но вот что все же вышло из моих попыток...

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/utsname.h>
 
 
typedef struct
{
    char str[20];
} slovo;
 
    slovo list[100];
 
typedef struct
{
    long lb, ub;
    pthread_cond_t cond;
} par;
 
pthread_t thread[3];
pthread_mutex_t mutex;
pthread_cond_t cond[3];
 
 
void merge(long lb, long split, long ub, pthread_cond_t cnd)
{
 
    long pos1=lb;
    long pos2=split+1;
    long pos3=0;    slovo *temp = new slovo[ub-lb+1];
    pthread_mutex_lock(&mutex); //захват мьютекса
    pthread_cond_signal(&cnd); //сигнал
    while (pos1 <= split && pos2 <= ub) {
        if (strcmp(list[pos1].str, list[pos2].str)<0)
            strcpy(temp[pos3++].str, list[pos1++].str);
        else
            strcpy(temp[pos3++].str, list[pos2++].str);
    }
 
    while (pos2 <= ub)
        strcpy(temp[pos3++].str, list[pos2++].str);
    while (pos1 <= split)
        strcpy(temp[pos3++].str, list[pos1++].str);
 
 
    for (pos3 = 0; pos3 < ub-lb+1; pos3++)
        strcpy(list[lb+pos3].str, temp[pos3].str);
    pthread_mutex_unlock(&mutex); // освобождение мьютекса
 
 
}
 
static void *mergeSort(void *_pParam)
{
    par *n = (par*) _pParam;
    int rc2, rc3, cn1, cn2;
    long split;
    par *n1 = (par*)malloc(sizeof(par)), *n2 = (par*)malloc(sizeof(par));
    pthread_mutex_lock(&mutex); //захват мьютекса
    if (n->lb < n->ub)
    {
        split = (n->lb + n->ub)/2;
 
        n1->lb = n->lb;
        n1->ub = split;
        n2->lb = split + 1;
        n2->ub = n->ub;
        cn1 = pthread_cond_init(&cond[0], NULL); //
        cn2 = pthread_cond_init(&cond[1], NULL); //инициализации условных переменных для передачи след потокам
        n1->cond = cond[0];
        n2->cond = cond[1];
        rc2 = pthread_create(&thread[0], NULL, mergeSort, (void*)n1);
        rc3 = pthread_create(&thread[1], NULL, mergeSort, (void*)n2);
        if(pthread_cond_wait(&n->cond, &mutex) == 0)
        merge(n->lb, split, n->ub, n->cond);
    }
    pthread_mutex_unlock(&mutex); //освобождение мьютекса
 
    return 0;
}
 
 
 
 
 
int main (int argc, char **argv)
{
    int cnt = 0;
    int rc1, rm;
    char str[101];
    printf("Vvedite slova: ");
    gets(str);
    char *ptr = strtok(str,"\t ");
    for(cnt=0; ptr!=NULL; cnt++)
    {
        strcpy(list[cnt].str, ptr);
        ptr = strtok(NULL,"\t ");
    }
    par *n1 = (par*)malloc(sizeof(par));
    n1->lb = 0;
    n1->ub = cnt - 1;
    int rc = pthread_cond_init(&cond[2], NULL);
    n1->cond = cond[2];
    rm = pthread_mutex_init(&mutex, NULL);
    rc1 = pthread_create(&thread[2], NULL, mergeSort, (void*)n1);
    pthread_join(thread[2], NULL);
    strcpy(str,"");
    for(int i=0;i<cnt;i++)
    {
        strcat(str,list[i].str);
        strcat(str," ");
    }
    puts("Result: \n"); puts(str);
    int c;
    scanf("%d", &c);
    return 0;
}
Если синхронизировать с помощью просто мьютекса, то результат получается правильным только частичто, т. е. создается такое ощущение, что пропускается пара итераций...

Буду благодарен любой помощи.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.05.2010, 00:05
Ответы с готовыми решениями:

Синхронизация потоков
Программа должна работать так: один поток печатает свой id пишет время, спит 20 секунд, потом опять пишет время. После завершения работы...

Синхронизация потоков. Нужны ли они?
Задание: Выполнить индивидуальное задание параллельным алгоритмом (обязательно использовать для разграничения общих ресурсов системные...

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

2
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.05.2010, 00:39
поясните задание.
разобраться в вашем коде, и понять что именно вам требуется - не просто
0
0 / 0 / 1
Регистрация: 13.04.2009
Сообщений: 38
11.05.2010, 01:26  [ТС]
Сейчас попробую разъяснить все как можно подробней. После запуска программы с клавиатуры вводится строка слов. Строка разбивается на слова и сохраняется как массив слов. mergeSort - это функция которая запускается как поток, она разбивает массив пополам до мельчайших элементов которые можно сравнить. После разбивки данные посылаются в merge, которая представляет собой функцию сортровки мельчайших элементов. Вот вроде и все. дело в том что mergeSort рекурсивно создает свои потоки. Нужно синхронизировать эти потоки

Добавлено через 3 минуты
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/utsname.h>
 
 
typedef struct
{
        char str[20];
} slovo;
 
        slovo list[100];
 
typedef struct
{
        long lb, ub;
        pthread_cond_t cond;
} par;
 
pthread_t thread[3];
pthread_mutex_t mutex;
pthread_cond_t cond[3];
 
 
void merge(long lb, long split, long ub, pthread_cond_t cnd) ..собственно фушкция изменения положения элемента в массиве, т. е. сортировка 2-х рассматриваемых элементов
{
 
        long pos1=lb;
        long pos2=split+1;
        long pos3=0;    slovo *temp = new slovo[ub-lb+1];
        pthread_mutex_lock(&mutex); //захват мьютекса
        pthread_cond_signal(&cnd); //сигнал
        while (pos1 <= split && pos2 <= ub) {
                if (strcmp(list[pos1].str, list[pos2].str)<0)
                        strcpy(temp[pos3++].str, list[pos1++].str);
                else
                        strcpy(temp[pos3++].str, list[pos2++].str);
        }
 
        while (pos2 <= ub)
                strcpy(temp[pos3++].str, list[pos2++].str);
        while (pos1 <= split)
                strcpy(temp[pos3++].str, list[pos1++].str);
 
 
        for (pos3 = 0; pos3 < ub-lb+1; pos3++)
                strcpy(list[lb+pos3].str, temp[pos3].str);
        pthread_mutex_unlock(&mutex); // освобождение мьютекса
 
 
}
 
static void *mergeSort(void *_pParam)
{
        par *n = (par*) _pParam;
        int rc2, rc3, cn1, cn2;
        long split;
        par *n1 = (par*)malloc(sizeof(par)), *n2 = (par*)malloc(sizeof(par));
        pthread_mutex_lock(&mutex); //захват мьютекса
        if (n->lb < n->ub)
        {
                split = (n->lb + n->ub)/2;
 
                n1->lb = n->lb;
                n1->ub = split;
                n2->lb = split + 1;
                n2->ub = n->ub;
                cn1 = pthread_cond_init(&cond[0], NULL); //
                cn2 = pthread_cond_init(&cond[1], NULL); //инициализации условных переменных для передачи след потокам
                n1->cond = cond[0];
                n2->cond = cond[1];
                rc2 = pthread_create(&thread[0], NULL, mergeSort, (void*)n1); //В потоке создается еще 2 потока (рекурсивно)
                rc3 = pthread_create(&thread[1], NULL, mergeSort, (void*)n2);//
                if(pthread_cond_wait(&n->cond, &mutex) == 0)
                merge(n->lb, split, n->ub, n->cond);
        }
        pthread_mutex_unlock(&mutex); //освобождение мьютекса
 
        return 0;
}
 
 
 
 
 
int main (int argc, char **argv)
{
        int cnt = 0;
        int rc1, rm;
        char str[101];
        printf("Vvedite slova: ");
        gets(str);
        char *ptr = strtok(str,"\t ");
        for(cnt=0; ptr!=NULL; cnt++)
        {
                strcpy(list[cnt].str, ptr);
                ptr = strtok(NULL,"\t ");
        } //Досюда строка разбивается на слова
        par *n1 = (par*)malloc(sizeof(par));
        n1->lb = 0;
        n1->ub = cnt - 1;
        int rc = pthread_cond_init(&cond[2], NULL);
        n1->cond = cond[2];
        rm = pthread_mutex_init(&mutex, NULL);
        rc1 = pthread_create(&thread[2], NULL, mergeSort, (void*)n1); // запуск первого потока
        pthread_join(thread[2], NULL);
        strcpy(str,"");
        for(int i=0;i<cnt;i++)
        {
                strcat(str,list[i].str);
                strcat(str," ");
        }
        puts("Result: \n"); puts(str);
        int c;
        scanf("%d", &c);
        return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.05.2010, 01:26
Помогаю со студенческими работами здесь

синхронизация потоков
проблема в следующем: есть 2 потока один считает некоторую сумму в цикле по столбцам матрицы второй должен выводить промежуточную...

Синхронизация потоков
Нужно: Выполнение нескольких арифметических операций разного приоритета. Оперировать с помощью мьютексов и кретических секций, как...

Синхронизация потоков
Всем привет. Вообщем есть клиент серверное приложение чат с функциями обмена сообщений и передачи файлов. Проблема в передаче файлов,...

Синхронизация потоков с++
Реализовать модуль создающий 4 балансировочных потока обеспечивающий 100% загрузку CPU (A,B,C,D). Каждый поток должен выводить на консоль...

Синхронизация потоков
Как переделать с использованием mutex или еще чего нибудь? /*Три нити. Одна генерирует тройки чисел, вторая решает...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru