С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1

Создание семафора

16.03.2013, 08:30. Показов 3765. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Запускаю код на одной машине все работает, на другой выдает ошибку "Error: can't init semaphore."
Ошибка возникает при открытии семафора.
Переменная key = 1234.
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
int Semaphore::open(int *pcreated)
{
    int id = 0;     // результат
    *pcreated = 0;  // семафор не создан
 
    // попытаться получить семафор
    if((id = semget(key, 1, 0)) == -1)
    {
        // не удалось, рассмотрим причину
        if (errno = ENOENT)
        {
            // запрощенный семафор не существует
            // создаем его
            if((this->id = semget(key, 1, IPC_CREAT | 0664)) == -1)
            {
                printf("Error: can't create semaphore.\n");
                return id;
            }
            *pcreated = 1;  // семафор был создан
        }
        else
        {
            printf("Error: can't get semaphore.\n");
            return id;
        }
    }
 
    // инициализировать семафор, если текущий процесс его создал
    if (*pcreated)
    {
        // структура данных для управления семафором
#ifndef _SEM_SEMUN_UNDEFINED_
    union semun
    {
        int val;                    // значение для команды SETVAL
        struct semid_ds *buf;       // буфер для команд IPC_STAT и IPC_SET
        unsigned short int *array;  // массив для команд GETALL и SETALL
        struct seminfo *__buf;      // буфер для команд IPC_INFO
    };
#endif
        union semun s_un;
        // начальное значение семафора
        s_un.val = 1;
        // установить начальное значение семафора
        if (semctl(id, 0, SETVAL, s_un) == -1)
        {
            printf("Error: can't init semaphore.\n");
            // с семафором работать нельзя
            return -1;
        }
    }
 
    return id;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.03.2013, 08:30
Ответы с готовыми решениями:

Получить значение счетчика семафора
Как можно вывести значение счетчика (chislo) семафора в данный момент(каждое изменение) sem_init(&sem, 0, chislo); //вдруг...

Реализовать двумя потоками запись в память и вывод строки с помощью семафора.
два процесса с разделенной памятью один процесс записывает строку в память другой после записи каждой строки выводит её на печать...

Превишен таймаут семафора
Всем привет! Quad 6600,Nvidia 680 i SLi,Жесткий диск WDC WD15 1.5 терабайт,разбит на 3 раздела! При копировании с одного раздела на...

4
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
16.03.2013, 10:46
Смотрите что записано в errno
0
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
18.03.2013, 21:31  [ТС]
Странно, перестала выдаваться ошибка "Error: can't init semaphore.". Но результать оказывается два раза больше чем надо.

main.cpp
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
#include "semaphore.h"
 
double calculate(char filename[128])
{
    FILE *fInput;
    double n = 0, result = 0;
 
    if ((fInput = fopen(filename, "r")) != NULL)
    {
        while (!feof(fInput))
        {
            fscanf(fInput, "%lf", &n);
            result += n;
        }
    }
    else
    {
        printf("Error! Can't open file \"%s\".",filename);
    }
 
    fclose (fInput);
 
    return result;
}
 
int main(int argc, char *argv[])
{
    double sum = 0;
    Semaphore semaphore;
 
    if (argc < 2)
    {
        printf("Usage %s[list of file names].", argv[0]);
        return -1;
    }
 
    if (semaphore.id != -1)
    {
        fopen("res.txt", "w");
 
        for(int i = 1; i < argc; i++ )
        {
            pid_t pid = fork();
 
            if(pid != 0)
            {
                double result = calculate(argv[i]);
 
                if (semaphore.lock() != 0)
                {
                    printf("Error! Can't lock %d semaphore, fork №%d!\n", semaphore.id, i);
                    return -1;
                }
 
                sum = 0;
 
                FILE *fOutput;
                if((fOutput = fopen("res.txt", "r")) != NULL)
                {
                    fscanf(fOutput,"%lf", &sum);
                }
                else
                {
                    printf("Error! Cant work with result file\n");
                    return -1;
                }
 
                sum += result;
 
                if((fOutput = fopen("res.txt", "w")) != NULL)
                {
                    fprintf(fOutput,"%lf", sum);
                }
 
                fclose(fOutput);
 
                if(semaphore.unlock() != 0)
                {
                    printf("Error! Can't unlock %d sem, fork №%d!\n", semaphore.id, i);
                    return -1;
                }
 
                return 0;
            }
        }
    }
    else
    {
        return -1;
    }
}
semaphore.cpp
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
#include "semaphore.h"
 
#define key 1234
 
Semaphore::Semaphore()
{
    id = open();
}
 
int Semaphore::open()
{
 
    int id = 0;     // результат
    bool pcreated = false;  // семафор не создан
 
    // попытаться получить семафор
    if((id = semget(key, 1, 0)) == -1)
    {
        // не удалось, рассмотрим причину
        if (errno = ENOENT)
        {
            // запрощенный семафор не существует
            // создаем его
            if((id = semget(key, 1, IPC_CREAT | 0664)) == -1)
            {
                printf("Error: can't create semaphore.\n");
                return id;
            }
            pcreated = true;  // семафор был создан
        }
        else
        {
            printf("Error: can't get semaphore.\n");
            return id;
        }
    }
 
    // инициализировать семафор, если текущий процесс его создал
    if (pcreated)
    {
        // структура данных для управления семафором
#ifndef _SEM_SEMUN_UNDEFINED_
    union semun
    {
        int val;                    // значение для команды SETVAL
        struct semid_ds *buf;       // буфер для команд IPC_STAT и IPC_SET
        unsigned short int *array;  // массив для команд GETALL и SETALL
        struct seminfo *__buf;      // буфер для команд IPC_INFO
    };
#endif
        union semun s_un;
        // начальное значение семафора
        s_un.val = 1;
        // установить начальное значение семафора
        if (semctl(id, 0, SETVAL, s_un) == -1)
        {
            printf("Error: can't init semaphore.\n");
            // с семафором работать нельзя
            return -1;
        }
    }
 
    return id;
}
 
int Semaphore::lock()
{
    struct sembuf s_buf = {0, -1, 0};
 
    if (semop(id, &s_buf, 1) == -1)
    {
        // проверяем причину
        if (errno == EIDRM)
        {
            // семафор был удален другим процессом
            return -1;
        }
        return 1;
    }
 
    return 0;
}
 
int Semaphore::unlock()
{
    struct sembuf s_buf = {0, 1, 0};
 
    if (semop(id, &s_buf, 1) == -1) {
        return 1;
    }
 
    return 0;
}
 
int Semaphore::close()
{
    semctl(id, 0, IPC_RMID, 0);
    return 0;
}
Добавлено через 6 минут
Почему-то данные с каждого входного файла считываются два раза. Как такое может быть?
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
20.03.2013, 15:01
Цитата Сообщение от Khelleos Посмотреть сообщение
C++
1
2
3
4
5
fopen("res.txt", "w");
for(int i = 1; i < argc; i++ )
{
  pid_t pid = fork(); 
  if(pid != 0)
Странный у вас кусок кода! Зачем fopen без получения указателя на файл?
Далее про форк. В мануале написано:

Bash
1
2
RETURN VALUE
On success, the PID of the child process is returned in the parent, and 0 is returned in the child.  On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
У вас условное выражение выполняет роидтельский процесс - тогда зачем fork?

По удвоенной сумме: может быть вы не совсем чисто соблюли условия тестирования? Я не запускал, но по коду что-то не видно, чтобы было удвоение.
0
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
22.03.2013, 20:59  [ТС]
Цитата Сообщение от grgdvo Посмотреть сообщение
Странный у вас кусок кода! Зачем fopen без получения указателя на файл?
нужно было просто создать пустой файл или очистить его в случае, если он создан. Просто это первое, что пришло в голову, но
решение проблемы дурацкое...

Цитата Сообщение от grgdvo Посмотреть сообщение
У вас условное выражение выполняет роидтельский процесс - тогда зачем fork?
Оуу...я думал fork вернёт id дочерного процесса, если он его создаст. Спасибо, не знал об этом.

Цитата Сообщение от grgdvo Посмотреть сообщение
По удвоенной сумме: может быть вы не совсем чисто соблюли условия тестирования? Я не запускал, но по коду что-то не видно, чтобы было удвоение.
Функция calculate выполняется два раза, при этом все условия соблюдены. Просто на одной машине все рабоет верно, на другой нет(сумма в два раза больше, чем должна быть)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.03.2013, 20:59
Помогаю со студенческими работами здесь

Превышен таймаут семафора
Ошибка 0x80070079 (Превышен таймаут семафора) в Windows 10 при создании образа системы.

Превышен таймаут семафора
Здох диск. Разбит на два логических Первый (с системой) говорит, что превышен таймаут семафора. Второй вообще не отзывается. Что...

Работа семафора в разных процессах
Процессы: Reder и несколько Sender'ов Собственно, есть семафор который управляет доступом к файлу... Реализован он в Reder'e и нужно...

Реализация семафора в ядре Linux
SUSE Linux 11.1 ядро 2.6.27.7-9 * интересует где находится реализация семафора и как подлючить при написании программы ...

Использование семафора для сигнализирования
Хочу разобраться с семафорами. Для начала для того чтобы сигнализироваться. вот допустим у нас такой код public class Semaphore { ...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru