UNIX и семафоры (программа на С)
помогите разобраться с си кодом...
вот код
// time_server v0.1
// time сервер который разделяет память
// использование семафоров для реализации блокировки
// разделяемая память используется программой по ключу 99
// семафорный набор используется программой по ключу 9900
#include stdio.h
#include sys/shm.h
#include time.h
#include sys/types.h
#include sys/sem.h
#define TIME_MEM_KEY 99
#define TIME_SEM_KEY 9900
#define SEG_SIZE ((size_t)100) /* размер сегмента */
#define oops(m,x) { perror(m); exit(x); }
union semun { int val ; struct semid_ds *buf ; ushort *array; };
int seg_id, semset_id; //глобальные переменные для cleanup()
void cleanup(int);
main ()
{
char *mem_ptr, *ctime();
time_t now;
int n;
//создание разделяемого сегмента памяти
seg_id = shmget(TIME_MEM_KEY, SEG_SIZE, IPC_CREAT|0777);
if (seg_id == -1)
oops("shmget",1);
//присоединение сигмента и получение указателя на сегмент
mem_ptr = shmat(seg_id, NULL, 0)
if (mem_ptr == (void *) -1)
oops("shmat", 2);
//создание набора семафоров semset: ключ 9900, 2 семафора и права доступа rw-rw-rw-
semset_id = semget(TIME_SEM_KEY, 2, (0666|IPC_CREAT|IPC_EXCL));
if (semset_id == -1)
oops("semget", 3);
set_sem_value(semset_id, 0, 0); //установка счетчиков в 0
set_sem_value(semset_id, 1, 0);
signal(SIGINT, cleanup);
// запуск на исполнение в течении минуты
for (n=0; n<60; n++)
{
time(&now); //получение значния текущего времени
printf("\time_server waiting for lock\n");
wait_and_lock(semset_id); // блокировка памяти
printf("\time_server updating memory\n");
strcpy(mem_ptr, ctime(&now)); //запись в память
sleep(5);
release_lock(semset_id); //снятие блокировки
printf("\time_server released lock\n");
sleep(1); // ждать 1 секунду
}
cleanup(0);
}
void cleanup(int n)
{
shmctl(seg_id, IPC_RMID, NULL); //удалить разделяемую память
semctr(semset_id, 0, IPC_RMID, NULL); //удалить семафорный набор
}
// инициализация семафора
set_sem_value(int semset_id, int semnum, int val)
{
union semun initval;
initval.val = val;
if (semctr(semset_id, semnum, SETVAL, initval) == -1)
oops("semctr", 4);
}
//построение и выполнение набора действий над элементами:
//ожидать достижение 0 на количестве читателей (n_readers) и
//инкремент счетчика количества писателей (n_writers)
wait_and_lock(int semset_id)
{
struct sembuf actions[2]; //набор действий
actions[0].sem_num = 0; // sem[0] - это счетчик n_readers
actions[0].sem_flg = SEM_UNDO; //автоматическое востановление
actions[0].sem_op = 0; //ожидать когда счетчик читателей достигнет нуля
actions[1].sem_num = 1; //sem[1] - это счетчик n_writers
actions[1].sem_flg = SEM_UNDO; //автоматическое востановление
actions[1].sem_op = +1; //инкремент счетчика писателей
if (semop(semset_id, actions, 2) == -1)
oops("semop:locking", 10);
}
//построение и выполнение набора действий из одного элемента
//декремент счетчика n_writers
release_lock(int semset_id)
{
struct sembuf actions[1]; //набор действий
actions[0].sem_num = 1 // sem[0] - это счетчик n_writers
actions[0].sem_flg = SEM_UNDO; //автоматическое востановление
actions[0].sem_op = -1 // декремент счетчика писателей
if (semop(semset_id, actions, 1) == -1)
oops ("semop: unlocking", 10);
}
ругаеться на красную строчку говорит error: redefinition of 'union semun'
что я не правильно написал?
- Для комментирования войдите или зарегистрируйтесь
А это
А это действительно Вы писали код? :)
Вам же ведь по английски компилятор говорит, что такая структура уже где-то определена, а вы еще раз ее определяете... Замените что ли на union my_semun { int val ; struct semid_ds *buf ; ushort *array; };
Ну и еще в коде местами знак ";" забыт...
needinfo
и все? приведи полный текст матерных высказываний gcc
_________________
~? **!
А вот в sem.h
error: redefinition of 'union semun'
"Ошибка: Вы заново определили 'union semun'",
а он уже в sem.h определён
спасибо
спасибо большое!
пока дальше буду разбираться в коде.
код писал не я код из книжки "програмирование под Unix\linux" просто не понятно немного пока =)
спасибо за помошь еще раз...
продолжение...
продолжение...
получилось так прога заработала я с ней разобрался,
но в ней есть один косяк...
если семафор существует то его использовать нельзя...
пытался исправить не получилось =(
вот посмотрите код и скажите пожалуйста в чем я не прав...
синем выделен кусок кода отвечающий за получение сушествующего набора семафоров
так вот не получает он =((
говорит
semctr: Invalid argument
time_server has exited with status 4.
это значит что ошибка в конце синего кода где то ... какой такой аргумент у него инвалид???
кажеться что semset_id... так как по моему мнению он хранит не идентифекатор семафора, а код ошибки о том что семафор сушествует.
правильно?
если да то как исправить?
как получить сам идентифекатор сушествуешего семафора?
семафоры
Следует проверить что второй параметр точно соответствует ко-ву семафоров созданных ранее. Ибо в уже существующем семафоре нельзя изменять их количество. Второе предположение что вместо 0666 лучше использовать SEM_R.
Третье во втором вызове лучше использовать SEM_R|IPC_CREATE.
И еще semget вроде как int должна возвращать => нет нужды преобразовывать b к void*
PS. А почему не POSIX семафоры?
Советую прочитать книжку Уильям Стивенсон "UNIX взаимодействие процессов".
Если дебаг это процесс удаления ошибок то программирование это процесс их внесения!
спасибо
спасибо разобрался =)
все заработало =)