Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/27: Рейтинг темы: голосов - 27, средняя оценка - 4.67
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295

Синхронизация процессов при помощи мьютексов

13.11.2009, 10:58. Показов 5530. Ответов 24

Студворк — интернет-сервис помощи студентам
начал разбираться с мбютексами, а точнее как синхронизировать 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
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
 
pthread_mutex_t work_mutex;
 
pid_t makeproc(void)
{
    pid_t pid;
 
    if((pid = fork())<0)
    {
       printf("fork faled\n");
       exit(1);
    }
    else return pid;
}
int my_mutex_init(void)
{
    int res;
    res = pthread_mutex_init(&work_mutex, NULL);
    if(res != 0)
    {
        printf("Mutex init falled!\n");
        exit(1);
    }
    else return res;
}
 
int main(void)
{
    pid_t pid;
    int res, iLenStr;
 
    res = my_mutex_init();
 
    pid = makeproc();
 
       switch(pid)
    {
        case 0:
        {
            pthread_mutex_lock(&work_mutex);
 
            printf("this is a child\n");
            sleep(20);
 
            printf("lock child - finish\n");
        
            pthread_mutex_unlock(&work_mutex);
 
 
        }break;
 
        default:
        {
 
            sleep(2);
            pthread_mutex_lock(&work_mutex);
 
            printf("this is a parent\n");
            sleep(10);
 
            printf("lock parent - finish\n");         
 
            pthread_mutex_unlock(&work_mutex);
 
        }break;
    }
 
 
 
}
Добавлено через 1 минуту
по идее, чайлд процес должен залочить мьютекс первым и подождав 20 сек вывести сообщение что он разлочился. потом лочит перент, ждет 10 и выводит что он тоже.

результат - не лочит никто. что я неправильно сделал?
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.11.2009, 10:58
Ответы с готовыми решениями:

синхронизация процессов с использованием мьютексов
помогите, не могу найти информацию для работы с мьютексами для синхронизации процессов

помогите .пожалуйста при помощи ЦИКЛИЧЕСКИХ ПРОЦЕССОВ
Кинетическая энергия движущегося тела W=m*v2/2, где m - масса тела, v - его скорость. Составить алгоритм для получения зависимости W от...

Синхронизация процессов
Добрый день! Прошу помощи в следующем вопросе: Есть некое консольное приложение на C#, которое производит работу с двумя файлами...

24
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
13.11.2009, 22:04
Скомпилировал у себя. Запустил.
Code
1
2
3
4
this is a child
this is a parent
lock child - finish
lock parent - finish
Вроде то, что и ожидалось.
0
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
13.11.2009, 22:09  [ТС]
нет, по идее он же должен так -

this is a child
lock child - finish
this is a parent
lock parent - finish
Добавлено через 25 секунд
ну - чайлд залочил - и пока не разлочил мьютекс - перент не вякает

Добавлено через 4 минуты
разве нет?
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
13.11.2009, 22:12
Неа. Потому что мьютексы работают на потоках, а ты создаешь процессы - т.е. два разных адресных пространства.
0
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
13.11.2009, 22:20  [ТС]
т.е. необходимо применять семафоры, так?

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
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
 
#define BUF_SIZE 1024
 
char buf[BUF_SIZE];
sem_t bin_sem;
 
pid_t makeproc(void)
{
    pid_t pid;
 
    if((pid = fork())<0)
    {
       printf("fork faled\n");
       exit(1);
    }
    else return pid;
}
 
 
int my_sem_init(void)
{
    int res;
   res = sem_init(&bin_sem,  0, 0);
    if(res != 0)
   {
       printf("semaphore init falled!\n");
        exit(1);
   }
   else return res;
}
 
int main(void)
{
    pid_t pid;
    char *message;
    int res, iLenStr;
 
   res = my_sem_init();
    
 
    pid = makeproc();
 
    switch(pid)
    {
        case 0:
        {
            printf("this is a child\n");
            sleep(6);
 
            printf("lock child - finish\n");
 
            sem_post(&bin_sem);
 
        }break;
 
        default:
        {
 
           sem_wait(&bin_sem);
 
            printf("this is a parent\n");
            sleep(4);
 
            printf("lock parent - finish\n");
 
          }break;
    }
 
sem_destroy($bin_sem);
 
}
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
13.11.2009, 22:23
Ну я не знаю чего ты хочешь. Если синхронизировать _потоки_, так тогда создавай потоки pthread_create. Синхронизировать _процессы_ - можно юзать семафоры.
0
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
13.11.2009, 22:24  [ТС]
смотри постом выше=) именно процессы=)
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
13.11.2009, 22:38
Накидал свой код. Родитель ожидает разрешение на пропуск от семафора. Потомок выполняет свои действия и открывает семафор родителю.
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
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
 
#define KEY 1147
 
int
main(void)
{
    pid_t pid;
    int semid;
    struct sembuf sem_wait[2] = { {0, -1, 0}, {0, 1, 0} };
 
    if( (semid = semget(KEY, 2, 0666 | IPC_CREAT)) < 0) {
        perror("semget");
        return -1;
    }
 
    if( (pid = fork()) < 0) {
        perror("fork");
        return -1;
    }
 
    if(pid > 0) {                        /* процесс родитель */
        semop(semid, &sem_wait[0], 1);   /* ждем пока разлочится семафор */
        printf("parent: sem unlocked\n");
    } else {                             /* дочерний процесс */
        printf("child: sem locked\n");
        semop(semid, &sem_wait[1], 1);   /* разлочиваем семафор */
 
    }
    return 0;
}
0
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
14.11.2009, 00:48  [ТС]
ммм.. попробовал твой пример применить для того чтобы разобраться - либо я чгео то не понимаю... но по моему он не лочит=(

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
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
 
#define BUF_SIZE 1024
#define KEY 1147
 
char buf[BUF_SIZE];
 
//***********************************************
int my_semget(void)
{
    int sem_id;
 
    if( (sem_id = semget(KEY, 2, 0666 | IPC_CREAT)) < 0)
    {
        printf("semget falled");
        return -1;
    }
 
    else return sem_id;
}
 //*********************************************
 
pid_t makeproc(void)
{
    pid_t pid;
 
    if((pid = fork())<0)
    {
       printf("fork faled\n");
       exit(1);
    }
    else return pid;
}
 
//***********************************************
int main(void)
{
    pid_t pid;
    int sem_id;
    struct sembuf sem_wait[2] = { {0, -1, 0}, {0, 1, 0} };
 
 
    pid = makeproc();
 
    if(pid > 0)
    {
        semop(sem_id, &sem_wait[0], 1);
        printf("parent: sem unlocked\n");
 
        printf("len = %i", strlen(buf));
 
    }
    else
    {
        printf("child: sem locked\n");
 
        printf("enter data: ");
        fgets(buf, BUF_SIZE, stdin);
 
        semop(sem_id, &sem_wait[1], 1);
 
    }
 
 
 
}

вот:

parent: sem unlocked
len = 0
press ENTER to continue
child: sem locked
enter data:
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
14.11.2009, 00:52
Акелла, потому что ты my_semget описал, но вызвать не вызвал.
1
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
14.11.2009, 01:01  [ТС]
заработало=) сенкс
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
14.11.2009, 01:05
Непонятно только нафига ты в одном процессе читаешь в буфер, а в другом выводишь его длину.
У каждого процесса свой независимый экземпляр переменной buf. Чтобы оба процесса видели изменение buf, нужно разместить его в разделяемой памяти или использовать прочие радости IPC.
1
Сонный металюга
 Аватар для Акелла
46 / 46 / 13
Регистрация: 10.05.2009
Сообщений: 295
14.11.2009, 01:09  [ТС]
я это уже понял - на самом деле я это делал просто для того чтобы увидеть - лочит или нет - с тем же успехом омно и просто принтф поставить каждый раз.

сейчас потренируюсь с разделяемой памятью заодно

Добавлено через 1 минуту
точнее с совместно используемой
1
 Аватар для Sergeymd
0 / 0 / 1
Регистрация: 13.09.2009
Сообщений: 45
02.12.2009, 20:39
Gravity вот к тебе вопрос твой код к примеру работает но если изменить 26-ую строку

условие на if(pid == 0) уже не работает тоесть работает но пишет
parent: sem unlocked
child: sem locked

а ведь не должно у нас же семафор стоит что то не как не пойму

и еще один вопрос значение KEY 1147 - произвольное выбирается?
и еще semget(KEY, 2, 0666 | IPC_CREAT); - 0666 тоже произвольное?

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
 #include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
 
#define KEY 1147
 
int
main(void)
{
    pid_t pid;
    int semid;
    struct sembuf sem_wait[2] = { {0, -1, 0}, {0, 1, 0} };
 
    if( (semid = semget(KEY, 2, 0666 | IPC_CREAT)) < 0) {
        perror("semget");
        return -1;
    }
 
    if( (pid = fork()) < 0) {
        perror("fork");
        return -1;
    }
 
    if(pid == 0) {                        /* процесс родитель */  /* !!!! было pid > 0 */
        semop(semid, &sem_wait[0], 1);   /* ждем пока разлочится семафор */
        printf("parent: sem unlocked\n");
    } else {                             /* дочерний процесс */
        printf("child: sem locked\n");
        semop(semid, &sem_wait[1], 1);   /* разлочиваем семафор */
 
    }
    return 0;
}/
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
02.12.2009, 21:19
Цитата Сообщение от Sergeymd Посмотреть сообщение
условие на if(pid == 0) уже не работает тоесть работает но пишет
parent: sem unlocked
child: sem locked
а ведь не должно у нас же семафор стоит что то не как не пойму
С чего бы не должно? В примере семафор всегда разлочивается вторым процессом.
Цитата Сообщение от Sergeymd Посмотреть сообщение
и еще один вопрос значение KEY 1147 - произвольное выбирается?
Произвольное.
Цитата Сообщение от Sergeymd Посмотреть сообщение
и еще semget(KEY, 2, 0666 | IPC_CREAT); - 0666 тоже произвольное?
0666 - права на идентификатор семафора, rw-rw-rw-.
1
 Аватар для Sergeymd
0 / 0 / 1
Регистрация: 13.09.2009
Сообщений: 45
02.12.2009, 21:22
я имею ввиду что все равно сообщение должно выводиться так:
child: sem locked
parent: sem unlocked

а оно не так выводит

ps:может я чего не понимаю я думал что семафор работает не важно с каким процессом, главное чтобы semop() было задано или не так?
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
02.12.2009, 21:29
Цитата Сообщение от Sergeymd Посмотреть сообщение
а оно не так выводит
Ну не знаю, у меня именно так и выводится. Либо у тебя ядро сконфигурировано особо извращенным способом, раз отказывается синхронизировать.
1
 Аватар для Sergeymd
0 / 0 / 1
Регистрация: 13.09.2009
Сообщений: 45
02.12.2009, 21:53
Gravity, то есть у тебя выводит
child: sem locked
parent: sem unlocked

даже если поменять условие на if(pid == 0)?

ps:у меня ubuntu 9.04 стоит
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
02.12.2009, 21:54
Sergeymd, ага. И собсно не вижу причин, чтобы смена pid процесса как-то на это влияла (разве что глюки в самой системе).
1
 Аватар для Sergeymd
0 / 0 / 1
Регистрация: 13.09.2009
Сообщений: 45
02.12.2009, 22:27
ну и я так вобще думал) я уже 2-ой день втыкаю

оно выводит то нормально, то не правильно

Добавлено через 28 минут
может быть из-за того что я ubuntu поставил на виртуальную машину?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.12.2009, 22:27
Помогаю со студенческими работами здесь

СИнхронизация процессов
Всем привет. Имеется несколько вопросов про синхронизацию процессов. - Что вобще такое &quot;синхронизация процессов&quot;?? С потоками...

Синхронизация процессов
Здравствуйте , помогите с синхронизацией процессов. Нужно создать 2 процесса дочерних и читать файл по 10 символов в течении 10 секунд либо...

Синхронизация процессов
какие существуют простые способы синхронизации процессов? из личного опыта, пожалуйста.

Синхронизация процессов
Добрый день уважаемые форумчане. Если ошибся разделом - поправьте. Вкратце опишу проблему. Есть терминальный сервер и некая...

Синхронизация процессов
Добрый вечер, форумчане! Имеется такая задача: Исходный процесс создает два программных информационных канала К1 и К2, канал...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru