Модифицируйте программы для корректной работы с помощью алгоритма Петерсона
15.09.2015, 22:17. Показов 1235. Ответов 0
Кликните здесь для просмотра всего текста
| 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
| #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int *array; /* Указатель на разделяемую память */
int shmid; /* IPC дескриптор для области разделяемой памяти */
int new = 1; /* Флаг необходимости инициализации элементов массива */
char pathname[] = "06-1a.c"; /* Имя файла,
используемое для генерации ключа. Файл с таким
именем должен существовать в текущей директории */
key_t key; /* IPC ключ */
/* Генерируем IPC ключ из имени файла 06-1a.c в
текущей директории и номера экземпляра области
разделяемой памяти 0 */
if((key = ftok(pathname,0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
/* Пытаемся эксклюзивно создать разделяемую память для
сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное
значение. Размер памяти определяем как размер массива
из трех целых переменных, права доступа 0666 – чтение
и запись разрешены для всех */
if((shmid = shmget(key, 3*sizeof(int),
0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае ошибки пытаемся определить: возникла ли она
из-за того, что сегмент разделяемой памяти уже существует
или по другой причине */
if(errno != EEXIST){
/* Если по другой причине – прекращаем работу */
printf("Can\'t create shared memory\n");
exit(-1);
} else {
/* Если из-за того, что разделяемая память уже
существует, то пытаемся получить ее IPC
дескриптор и, в случае удачи, сбрасываем флаг
необходимости инициализации элементов массива */
if((shmid = shmget(key, 3*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");
exit(-1);
}
new = 0;
}
}
/* Пытаемся отобразить разделяемую память в адресное
пространство текущего процесса. Обратите внимание на то,
что для правильного сравнения мы явно преобразовываем
значение -1 к указателю на целое.*/
if((array = (int *)shmat(shmid, NULL, 0)) == (int *)(-1)){
printf("Can't attach shared memory\n");
exit(-1);
}
/* В зависимости от значения флага new либо
инициализируем массив, либо увеличиваем
соответствующие счетчики */
if(new){
array[0] = 1;
array[1] = 0;
array[2] = 1;
} else {
array[0] += 1;
array[2] += 1;
}
/* Печатаем новые значения счетчиков, удаляем
разделяемую память из адресного пространства
текущего процесса и завершаем работу */
printf("Program 1 was spawn %d times,
program 2 - %d times, total - %d times\n",
array[0], array[1], array[2]);
if(shmdt(array) < 0){
printf("Can't detach shared memory\n");
exit(-1);
}
return 0;
} |
|
Кликните здесь для просмотра всего текста
| 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
| #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int *array; /* Указатель на разделяемую память */
int shmid; /* IPC дескриптор для области разделяемой памяти */
int new = 1; /* Флаг необходимости инициализации элементов массива */
char pathname[] = "06-1a.c"; /* Имя файла,
используемое для генерации ключа. Файл с таким
именем должен существовать в текущей директории */
key_t key; /* IPC ключ */
/* Генерируем IPC ключ из имени файла 06-1a.c в
текущей директории и номера экземпляра области
разделяемой памяти 0 */
if((key = ftok(pathname,0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
/* Пытаемся эксклюзивно создать разделяемую память
для сгенерированного ключа, т.е. если для этого
ключа она уже существует, системный вызов вернет
отрицательное значение. Размер памяти определяем
как размер массива из трех целых переменных, права
доступа 0666 – чтение и запись разрешены для всех */
if((shmid = shmget(key, 3*sizeof(int),
0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае возникновения ошибки пытаемся определить:
возникла ли она из-за того, что сегмент разделяемой
памяти уже существует или по другой причине */
if(errno != EEXIST){
/* Если по другой причине – прекращаем работу */
printf("Can\'t create shared memory\n");
exit(-1);
} else {
/* Если из-за того, что разделяемая память уже
существует, то пытаемся получить ее IPC дескриптор
и, в случае удачи, сбрасываем флаг необходимости
инициализации элементов массива */
if((shmid = shmget(key, 3*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");
exit(-1);
}
new = 0;
}
}
/* Пытаемся отобразить разделяемую память в адресное
пространство текущего процесса. Обратите внимание на то,
что для правильного сравнения мы явно преобразовываем
значение -1 к указателю на целое.*/
if((array = (int *)shmat(shmid, NULL, 0)) ==
(int *)(-1)){
printf("Can't attach shared memory\n");
exit(-1);
}
/* В зависимости от значения флага new либо
инициализируем массив, либо увеличиваем
соответствующие счетчики */
if(new){
array[0] = 0;
array[1] = 1;
array[2] = 1;
} else {
array[1] += 1;
array[2] += 1;
}
/* Печатаем новые значения счетчиков, удаляем разделяемую
память из адресного пространства текущего процесса и
завершаем работу */
printf("Program 1 was spawn %d times,
program 2 - %d times, total - %d times\n",
array[0], array[1], array[2]);
if(shmdt(array) < 0){
printf("Can't detach shared memory\n");
exit(-1);
}
return 0;
} |
|
Кликните здесь для просмотра всего текста
| 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
| /*Каждая нить исполнения просто увеличивает на 1 разделяемую
переменную a. */
#include <pthread.h>
#include <stdio.h>
int a = 0;
/* Переменная a является глобальной статической для всей
программы, поэтому она будет разделяться обеими нитями
исполнения.*/
/* Ниже следует текст функции, которая будет
ассоциирована со 2-м thread'ом */
void *mythread(void *dummy)
/* Параметр dummy в нашей функции не используется и
присутствует только для совместимости типов данных. По той
же причине функция возвращает значение void *, хотя
это никак не используется в программе.*/
{
pthread_t mythid; /* Для идентификатора нити исполнения */
/* Заметим, что переменная mythid является
динамической локальной переменной функции mythread(),
т. е. помещается в стеке и, следовательно, не разделяется
нитями исполнения. */
/* Запрашиваем идентификатор thread'а */
mythid = pthread_self();
a = a+1;
printf("Thread %d, Calculation result = %d\n",
mythid, a);
return NULL;
}
/* Функция main() – она же ассоциированная функция главного
thread'а */
int main()
{
pthread_t thid, mythid;
int result;
/* Пытаемся создать новую нить исполнения,
ассоциированную с функцией mythread(). Передаем ей
в качестве параметра значение NULL. В случае удачи в
переменную thid занесется идентификатор нового thread'а.
Если возникнет ошибка, то прекратим работу. */
result = pthread_create( &thid,
(pthread_attr_t *)NULL, mythread, NULL);
if(result != 0){
printf ("Error on thread create,
return value = %d\n", result);
exit(-1);
}
printf("Thread created, thid = %d\n", thid);
/* Запрашиваем идентификатор главного thread'а */
mythid = pthread_self();
a = a+1;
printf("Thread %d, Calculation result = %d\n",
mythid, a);
/* Ожидаем завершения порожденного thread'a, не
интересуясь, какое значение он нам вернет. Если не
выполнить вызов этой функции, то возможна ситуация,
когда мы завершим функцию main() до того, как выполнится
порожденный thread, что автоматически повлечет за
собой его завершение, исказив результаты. */
pthread_join(thid, (void **)NULL);
return 0;
} |
|
Кликните здесь для просмотра всего текста
| 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
| #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int *array; /* Указатель на разделяемую память */
int shmid; /* IPC дескриптор для области
разделяемой памяти */
int new = 1; /* Флаг необходимости инициализации
элементов массива */
char pathname[] = "06-3a.c"; /* Имя файла,
использующееся для генерации ключа. Файл с таким
именем должен существовать в текущей директории */
key_t key; /* IPC ключ */
long i;
/* Генерируем IPC ключ из имени файла 06-3a.c в
текущей директории и номера экземпляра области
разделяемой памяти 0 */
if((key = ftok(pathname,0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
/* Пытаемся эксклюзивно создать разделяемую память для
сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное
значение. Размер памяти определяем как размер массива
из 3-х целых переменных, права доступа 0666 – чтение и
запись разрешены для всех */
if((shmid = shmget(key, 3*sizeof(int),
0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае возникновения ошибки пытаемся определить:
возникла ли она из-за того, что сегмент разделяемой
памяти уже существует или по другой причине */
if(errno != EEXIST){
/* Если по другой причине – прекращаем работу */
printf("Can\'t create shared memory\n");
exit(-1);
} else {
/* Если из-за того, что разделяемая память уже
существует – пытаемся получить ее IPC дескриптор
и, в случае удачи, сбрасываем флаг необходимости
инициализации элементов массива */
if((shmid = shmget(key, 3*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");
exit(-1);
}
new = 0;
}
}
/* Пытаемся отобразить разделяемую память в адресное
пространство текущего процесса. Обратите внимание на то,
что для правильного сравнения мы явно преобразовываем
значение -1 к указателю на целое.*/
if((array = (int *)shmat(shmid, NULL, 0)) ==
(int *)(-1)){
printf("Can't attach shared memory\n");
exit(-1);
}
/* В зависимости от значения флага new либо
инициализируем массив, либо увеличиваем
соответствующие счетчики */
if(new){
array[0] = 1;
array[1] = 0;
array[2] = 1;
} else {
array[0] += 1;
for(i=0; i<1000000000L; i++);
/* Предельное значение для i может меняться в зависимости
от производительности компьютера */
array[2] += 1;
}
/* Печатаем новые значения счетчиков, удаляем разделяемую
память из адресного пространства текущего процесса и з
авершаем работу */
printf("Program 1 was spawn %d times,
program 2 - %d times, total - %d times\n",
array[0], array[1], array[2]);
if(shmdt(array) < 0){
printf("Can't detach shared memory\n");
exit(-1);
}
return 0;
} |
|
Кликните здесь для просмотра всего текста
| 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
| #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int *array; /* Указатель на разделяемую память */
int shmid; /* IPC дескриптор для области разделяемой памяти */
int new = 1; /* Флаг необходимости инициализации элементов массива */
char pathname[] = "06-3a.c"; /* Имя файла,
использующееся для генерации ключа. Файл с таким
именем должен существовать в текущей директории */
key_t key; /* IPC ключ */
long i;
/* Генерируем IPC ключ из имени файла 06-3a.c в текущей
директории и номера экземпляра области разделяемой
памяти 0 */
if((key = ftok(pathname,0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
/* Пытаемся эксклюзивно создать разделяемую память для
сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное
значение. Размер памяти определяем как размер массива
из трех целых переменных, права доступа 0666 – чтение
и запись разрешены для всех */
if((shmid = shmget(key, 3*sizeof(int),
0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае ошибки пытаемся определить, возникла ли она
из-за того, что сегмент разделяемой памяти уже существует
или по другой причине */
if(errno != EEXIST){
/* Если по другой причине – прекращаем работу */
printf("Can\'t create shared memory\n");
exit(-1);
} else {
/* Если из-за того, что разделяемая память уже
существует – пытаемся получить ее IPC дескриптор
и, в случае удачи, сбрасываем флаг необходимости
инициализации элементов массива */
if((shmid = shmget(key,
3*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");
exit(-1);
}
new = 0;
}
}
/* Пытаемся отобразить разделяемую память в адресное
пространство текущего процесса. Обратите внимание на то,
что для правильного сравнения мы явно преобразовываем
значение -1 к указателю на целое.*/
if((array = (int *)shmat(shmid, NULL, 0)) ==
(int *)(-1)){
printf("Can't attach shared memory\n");
exit(-1);
}
/* В зависимости от значения флага new либо
инициализируем массив, либо увеличиваем
соответствующие счетчики */
if(new){
array[0] = 0;
array[1] = 1;
array[2] = 1;
} else {
array[1] += 1;
for(i=0; i<1000000000L; i++);
/* Предельное значение для i может меняться в зависимости
от производительности компьютера */
array[2] += 1;
}
/* Печатаем новые значения счетчиков, удаляем разделяемую
память из адресного пространства текущего процесса и завершаем
работу */
printf("Program 1 was spawn %d times,
program 2 - %d times, total - %d times\n",
array[0], array[1], array[2]);
if(shmdt(array) < 0){
printf("Can't detach shared memory\n");
exit(-1);
}
return 0;
} |
|
модифицируйте программы для корректной работы с помощью алгоритма Петерсона.
0
|