Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
3 / 3 / 0
Регистрация: 14.09.2012
Сообщений: 84
1

Semaphore

30.03.2013, 18:09. Показов 1729. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Прочитал мануал по семафору, разобрал простой пример с его применением.
Но непонятно следующее предложение:
"Каждому элементу массива должен быть сопоставлен свой собственный семафор, предотвращающий одновременное обращение двух процессов к одним и тем же элементам."

Как это сделать? Тут вообще тьма.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.03.2013, 18:09
Ответы с готовыми решениями:

Объясните как работает Semaphore
При задании минимального кол-во запросов(5), как я понимаю семафор выполнит действие, если запросов...

Semaphore Wait(int millisecondsTimeout)
Добрый день. Разбираюсь в многопоточном программировании. Скажите пожалуйста, что именно означает...

Не могу найти класс Semaphore
Куда то делся етот классс. Студия 2012 Express. Когда пишу Semaphore подчекркивает красной...

Какое назначение у параметров Semaphore Constructor?
Имеется такой код применения семафора. using System; using System.Threading; // Этот поток...

5
Псевдослучайный
1946 / 1145 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
30.03.2013, 21:38 2
Вероятно, это про какой-то частный случай, когда есть массив, каждое отдельное значение в котором нужно читать/писать разным процессам и при этом ставить блокировку на весь массив сразу не выгодно. Соответственно, объект синхронизации тоже нужен для каждого элемента.
0
3 / 3 / 0
Регистрация: 14.09.2012
Сообщений: 84
31.03.2013, 09:01  [ТС] 3
Цитата Сообщение от NoMasters Посмотреть сообщение
Вероятно, это про какой-то частный случай, когда есть массив, каждое отдельное значение в котором нужно читать/писать разным процессам и при этом ставить блокировку на весь массив сразу не выгодно. Соответственно, объект синхронизации тоже нужен для каждого элемента.
Не подскажите как это можно организовать на примере для конкретного массива?
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
03.04.2013, 19:16 4
Цитата Сообщение от Penoplast Посмотреть сообщение
Не подскажите как это можно организовать на примере для конкретного массива?
Массив структур. В структуре два поля: семафор(мьютекс) и поле данных. Перед тем как записать/прочитать элемент массива, пытаемся захватить мьютекс.
1
3 / 3 / 0
Регистрация: 14.09.2012
Сообщений: 84
27.04.2013, 12:51  [ТС] 5
Написал прогу, но никак не исправить ошибки при сборке. Что я написал не так?

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
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
 
typedef struct ELEMENT_STRUCT
{
    int data;
    pthread_mutex_t mutex;
} ELEMENT;
 
void Init(ELEMENT *arr, int arr_size, int min, int max);
 
int main(int argc, const char *argv[])
{
    if (argc != 4) {
        printf("Syntax: Semaphore <number_count> <min_number> <max_number>");
        return 0;
    }
 
    srand(time(NULL));
 
    int arr_size = atoi(argv[1]);
    int arr_min = atoi(argv[2]);
    int arr_max = atoi(argv[3]);
 
    int shm_id = shmget(IPC_PRIVATE, sizeof(ELEMENT)*arr_size + sizeof(int), 0666);
    if (shm_id == -1) {
        printf("error: shmget()");
        return -1;
    }
 
    int *busy_flag = (int*)shmat(shm_id, NULL, 0);
    ELEMENT *arr = (ELEMENT*)++busy_flag;
    if (*busy_flag == -1) {
        printf("error: shmat()");
        return -1;
    }
    
    
    Init(arr, arr_size, arr_min, arr_max);
 
    pid_t pid = fork();
    if (pid < 0) {
        printf("error: fork()");
        return -1;
    }
 
    if (pid == 0) {
        //bubble sort
        ELEMENT tmp;
        for (int i = arr_size - 1; i > 0; --i) {
            for (int j = 0; j < i; ++j) {
                if (arr[j].data > arr[j+1].data) {
                    pthread_mutex_lock(&arr[j].mutex);
                    pthread_mutex_lock(&arr[j+1].mutex);
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                    pthread_mutex_unlock(&arr[j+1].mutex);
                    pthread_mutex_unlock(&arr[j].mutex);
                }
            }
        }
    }
 
    if (pid > 0) {
        int iteration_number = 0;
 
        do {
            printf("\n\niteration: %d\n", iteration_number);
            for (int i = 0; i < arr_size; ++i) {
                if (pthread_mutex_lock(&arr[i].mutex) == EDEADLK) {
                    printf("%d, locked\n", arr[i].data);
                    pthread_mutex_unlock(&arr[i].mutex);
                } else {
                    printf("%d, unlocked\n", arr[i].data);
                }
            }
        }
        while (*busy_flag);
 
        for (int i = 0; i < arr_size; ++i) {
            printf("%d ", arr[i].data);
            pthread_mutex_destroy(&arr[i].mutex);
        }
                   
        shmctl(shm_id, IPC_RMID, NULL);
    }
 
    return 0;
}
 
void Init(ELEMENT *arr, int arr_size, int min, int max) {
    for (int i = 0; i < arr_size; ++i) {
        pthread_mutexattr_t mattr;
        pthread_mutexattr_init(&mattr);
        pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
        
        pthread_mutex_init(&arr[i].mutex, &mattr);
        arr[i].data = rand() % max + min;
    }
}
Добавлено через 6 минут
Задание:
Основной процесс должен выделить область разделяемой памяти и заполнить ее N
случайными числами. Количество чисел, а также минимальное и максимальное допустимые
значения должны быть получены из параметров командной строки.
Каждому элементу массива должен быть сопоставлен свой собственный семафор,
предотвращающий одновременное обращение двух процессов к одним и тем же элементам.
После заполнения массива должен быть порожден второй процесс, который начнет
производить сортировку чисел по возрастанию.
Пока идет сортировка, первый процесс должен пытаться последовательно читать числа из
массива и выводить на экран их текущее значение и результат работы с семафором: удалось ли
получить доступ к числу сразу, или пришлось ждать освобождения семафора.
После окончания обхода массива первый процесс должен проверить, завершился ли уже
процесс сортировки. Если да - то вывести массив и завершиться. Если еще нет - то начать новую
итерацию обхода массива. В начале каждой итерации обхода требуется выводить ее порядковый
номер.
Проверку факта завершения дочернего процесса (без перевода текущего процесса в
состояние ожидания) можно сделать при помощи функции waitpid с параметром WHOHANG.
(подробнее см. man waitpid)
Второй процесс в ходе сортировки также должен проверять и выставлять семафор перед
обращением к каждому из элементов.
Далее первый процесс должен вывести на экран отсортированный массив. Второй
процесс не должен осуществлять никакого вывода на экран.
Первый процесс должен самостоятельно выполнить освобождение всех выделенных
ресурсов (в том числе семафоров) в конце своей работы.
0
3 / 3 / 0
Регистрация: 14.09.2012
Сообщений: 84
28.04.2013, 22:17  [ТС] 6
Ошибки при сборке исправил, но все равно на каком-то моменте прога зависает и ожидает освобождения мьютекса.

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
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
 
typedef struct ELEMENT_STRUCT
{
    int data;
    pthread_mutex_t mutex;
} ELEMENT;
 
void Init(ELEMENT *arr, int arr_size, int min, int max);
 
int main(int argc, const char *argv[])
{
    if (argc != 4) {
        printf("Syntax: Semaphore <number_count> <min_number> <max_number>");
        return 0;
    }
 
    srand(time(NULL));
 
    int arr_size = atoi(argv[1]);
    int arr_min = atoi(argv[2]);
    int arr_max = atoi(argv[3]);
 
    int shm_id = shmget(IPC_PRIVATE, sizeof(ELEMENT)*arr_size + sizeof(int), 0666);
    if (shm_id == -1) {
        printf("error: shmget()");
        return -1;
    }
 
    int *busy_flag = (int*)shmat(shm_id, NULL, 0);
    ELEMENT *arr = (ELEMENT*)++busy_flag;
    if (*busy_flag == -1) {
        printf("error: shmat()");
        return -1;
    }
    
    
    Init(arr, arr_size, arr_min, arr_max);
 
    pid_t pid = fork();
    if (pid < 0) {
        printf("error: fork()");
        return -1;
    }
 
    if (pid == 0) {
        //bubble sort
        ELEMENT tmp;
        for (int i = arr_size - 1; i > 0; --i) {
            for (int j = 0; j < i; ++j) {
                if (arr[j].data > arr[j+1].data) {
                    pthread_mutex_lock(&arr[j].mutex);
                    pthread_mutex_lock(&arr[j+1].mutex);
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                    pthread_mutex_unlock(&arr[j+1].mutex);
                    pthread_mutex_unlock(&arr[j].mutex);
                }
            }
        }
    }
 
    if (pid > 0) {
        int iteration_number = 0;
 
        do {
            printf("\n\niteration: %d\n", iteration_number);
            for (int i = 0; i < arr_size; ++i) {
                if (pthread_mutex_trylock(&arr[i].mutex) == EBUSY) {
                    pthread_mutex_lock(&arr[i].mutex);
                    printf("%d, locked\n", arr[i].data);
                    pthread_mutex_unlock(&arr[i].mutex);
                } else {
                    printf("%d, unlocked\n", arr[i].data);
                }
            }
        }
        while (*busy_flag);
 
        for (int i = 0; i < arr_size; ++i) {
            printf("%d ", arr[i].data);
            pthread_mutex_destroy(&arr[i].mutex);
        }
                   
        shmctl(shm_id, IPC_RMID, NULL);
    }
 
    return 0;
}
 
void Init(ELEMENT *arr, int arr_size, int min, int max) {
    for (int i = 0; i < arr_size; ++i) {
        pthread_mutexattr_t mattr;
        pthread_mutexattr_init(&mattr);
        pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
        
        pthread_mutex_init(&arr[i].mutex, &mattr);
        arr[i].data = rand() % max + min;
    }
}
Добавлено через 11 минут
Кое что еще раз исправил, но не работает как надо.

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
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
 
typedef struct ELEMENT_STRUCT
{
    int data;
    pthread_mutex_t mutex;
} ELEMENT;
 
void Init(ELEMENT *arr, int arr_size, int min, int max);
 
int main(int argc, const char *argv[])
{
    if (argc != 4) {
        printf("Syntax: Semaphore <number_count> <min_number> <max_number>");
        return 0;
    }
 
    srand(time(NULL));
 
    int arr_size = atoi(argv[1]);
    int arr_min = atoi(argv[2]);
    int arr_max = atoi(argv[3]);
 
    int shm_id = shmget(IPC_PRIVATE, sizeof(ELEMENT)*arr_size + sizeof(int), 0666);
    if (shm_id == -1) {
        printf("error: shmget()");
        return -1;
    }
 
    int *busy_flag = (int*)shmat(shm_id, NULL, 0);
    ELEMENT *arr = (ELEMENT*)++busy_flag;
    if (*busy_flag == -1) {
        printf("error: shmat()");
        return -1;
    }
    
    
    Init(arr, arr_size, arr_min, arr_max);
    *busy_flag = 0
 
    pid_t pid = fork();
    if (pid < 0) {
        printf("error: fork()");
        return -1;
    }
 
    if (pid == 0) {
        //bubble sort
        ELEMENT tmp;
        for (int i = arr_size - 1; i > 0; --i) {
            for (int j = 0; j < i; ++j) {
                if (arr[j].data > arr[j+1].data) {
                    pthread_mutex_lock(&arr[j].mutex);
                    pthread_mutex_lock(&arr[j+1].mutex);
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                    pthread_mutex_unlock(&arr[j+1].mutex);
                    pthread_mutex_unlock(&arr[j].mutex);
                }
            }
        }
     *busy_flag = 1;
    }
 
    if (pid > 0) {
        int iteration_number = 0;
 
        do {
            printf("\n\niteration: %d\n", iteration_number);
            for (int i = 0; i < arr_size; ++i) {
                if (pthread_mutex_trylock(&arr[i].mutex) == EBUSY) {
                    pthread_mutex_lock(&arr[i].mutex);
                    printf("%d, locked\n", arr[i].data);
                    pthread_mutex_unlock(&arr[i].mutex);
                } else {
                    printf("%d, unlocked\n", arr[i].data);
                }
            }
        }
        while (*busy_flag);
 
        for (int i = 0; i < arr_size; ++i) {
            printf("%d ", arr[i].data);
            pthread_mutex_destroy(&arr[i].mutex);
        }
                   
        shmctl(shm_id, IPC_RMID, NULL);
    }
 
    return 0;
}
 
void Init(ELEMENT *arr, int arr_size, int min, int max) {
    for (int i = 0; i < arr_size; ++i) {
        pthread_mutexattr_t mattr;
        pthread_mutexattr_init(&mattr);
        pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
        
        pthread_mutex_init(&arr[i].mutex, &mattr);
        arr[i].data = rand() % max + min;
    }
}
0
28.04.2013, 22:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.04.2013, 22:17
Помогаю со студенческими работами здесь

Как реализовать многопоток? (возможно Semaphore)
Здравствуйте, есть задача выполнять некий кусок кода разными небольшими программами в несколько...

Синхронизация потоков при использовании semaphore
Доброго времени суток! Есть глобальный массив. Есть два потока (main и second). Main выводит...

Сделать консольную программу парковки автомобилей используя класс Semaphore
Никак немогу совсем разобратсья c задачей .Нужно сделать консольную программу парковки автомобилей...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru