Руководство программиста для Linux


Семафоры - часть 8


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

semtool c (количество семафоров в множестве)

Запирание семафора

semtool l (номер семафора для запирания)

Отпирание семафора

semtool u (номер семафора для отпирания)

Изменение прав доступа (mode)

semtool m (mode)

Удаление множества семафоров

semtool d

Примеры semtool c 5

semtool l

semtool u

semtool m 660

semtool d

Исходный текст /**************************************************************************** Excerpt from "Linux Programmer's Guide - Chapter 6" (C)opyright 1994-1995, Scott Burkett **************************************************************************** MODULE: semtool.c **************************************************************************** Средство командной строки для работы со множествами семафоров в стиле SysV ****************************************************************************/ #include #include #include #include #include #include #define SEM_RESOURCE_MAX 1 /* Начальное значение для всех семафоров */ void opensem(int *sid, key_t key); void createsem(int *sid, key_t key, int members); void locksem(int sid, int member); void unlocksem(int sid, int member); void removesem(int sid); unsigned short get_member_count(int sid); int getval(int sid, int member); void dispval(int sid, int member); void changemode(int sid, char *mode); void usage(void); int main(int argc, char *argv[]) { key_t key; int semset_id; if(argc ==1) usage(); /* Создаем особый ключ через вызов ftok() */ key = ftok(".", 's'); switch(tolower(argv[1][0])) { case 'c': if(argc != 3) usage(); createsem(&semset_id, key, atoi(argv[2])); break; case 'l': if(argc != 3) usage(); opensem(&semset_id, key); locksem(semset_id, atoi(argv[2])); break; case 'u': if(argc != 3) usage(); opensem(&semset_id, key); unlocksem(semset_id, atoi(argv[2])); break; case 'd': opensem(&semset_id, key); removesem(semset_id); break; case 'm': opensem(&semset_id, key); changemode(semset_id, argv[2]); break; default: usage(); } return(0); } void opensem(int *sid, key_t key) { /* Открываем множество семафоров - не создаем! */ if((*sid = semget(key, 0, 0666)) == -1) { printf("Semaphore set does not exist!\n"); exit(1); } } void createsem(int *sid, key_t key, int members) { int cntr; union semun semopts; if(members > SEMMSL) { printf("Sorry, max number of semaphores in a set is %d\n", SEMMSL); exit(1); } printf("Attempting to create new semaphore set with %d members\n", members); if((*sid = semget(key, members, IPC_CREAT|IPC_EXCL|0666)) == -1) { fprintf(stderr, "Semaphore set already exists!\n"); exit(1); } semopts.val = SEM_RESOURCE_MAX; /* Инициализируем все элементы (может быть сделано с SETALL) */ for(cntr=0; cntr(get_member_count(sid)-1)) { fprintf(stderr, "semaphore member %d out of range\n", member); return; } /* Попытка запереть множество семафоров */ if(!getval(sid, member)) { fprintf(stderr, "Semaphore resources exhausted (no lock)!\n"); exit(1); } sem_lock.sem_num = member; if((semop(sid, &sem_lock, 1)) == -1) { fprintf(stderr, "Lock failed\n"); exit(1); } else printf("Semaphore resources decremented by one (locked)\n"); dispval(sid, member); } void unlocksem(int sid, int member) { struct sembuf sem_unlock={ member, 1, IPC_NOWAIT }; int semval; if( member<0 member>(get_member_count(sid)-1)) { fprintf(stderr, "semaphore member %d out of range\n", member); return; } /* Заперто ли множество семафоров? */ semval = getval(sid, member); if(semval == SEM_RESOURCE_MAX) { fprintf(stderr, "Semaphore not locked!\n"); exit(1); } sem_unlock.sem_num = member; /* Попытка запереть множество семафоров */ if((semop(sid, &sem_unlock, 1)) == -1) { fprintf(stderr, "Unlock failed\n"); exit(1); } else printf("Semaphore resources incremented by one (unlocked)\n"); dispval(sid, member); } void removesem(int sid) { semctl(sid, 0, IPC_RMID, 0); printf("Semaphore removed\n"); } unsigned short get_member_count(int sid) { union semun semopts; struct semid_ds mysemds; semopts.buf = &mysemds; /* Выдает количество элементов во множестве семафоров */ return(semopts.buf->sem_nsems); } int getval(int sid, int member) { int semval; semval = semctl(sid, member, GETVAL, 0); return(semval); } void changemode(int sid, char *mode) { int rc; union semun semopts; struct semid_ds mysemds; /* Получаем текущее значение для внутренней структуры данных */ semopts.buf = &mysemds; rc = semctl(sid, 0, IPC_STAT, semopts); if (rc == -1) { perror("semctl"); exit(1); } printf("Old permissions were %o\n", semopts.buf->sem_perm.mode); /* Изменяем права доступа к семафору */ sscanf(mode, "%ho", &semopts.buf->sem_perm.mode); /* Обновляем внутреннюю структуру данных */ semctl(sid, 0, IPC_SET, semopts); printf("Updated...\n"); } void dispval(int sid, int member) { int semval: semval = semctl(sid, member, GETVAL, 0); printf("semval for member %d is %d\n", member, semval); } void usage(void) { fprintf(stderr, "semtool - A utility for tinkering with semaphores\n"); fprintf(stderr, "\nUSAGE: semtool4 (c)reate \n"); fprintf(stderr, " (l)ock \n"); fprintf(stderr, " (u)nlock \n"); fprintf(stderr, " (d)elete\n"); fprintf(stderr, " (m)ode \n"); exit(1); } semstat: Программа-компаньон для semtool В дополнение к semtool, приведем исходный текст программы-компаньона semstat. Она выводит на экран значение каждого из семафоров множества, созданного посредством semtool. /**************************************************************************** Excerpt from "Linux Programmer's Guide - Chapter 6" (C)opyright 1994-1995, Scott Burkett **************************************************************************** MODULE: semstat.c **************************************************************************** Компаньон для cредства командной строки semtool-а. Semstat выводит на экран текущее значение всех семафоров множества, созданного посредством semtool. ****************************************************************************/ #include #include #include #include #include int get_sem_count(int sid); void show_sem_usage(int sid); int get_sem_count(int sid); void dispval(int sid); int main(int argc, char *argv[]) { key_t key; int semset_id; /* Создаем уникальный ключ через вызов ftok() */ key = ftok(".", 's'); /* Открываем множество семафоров - не создаем! */ if((semset_id = semget(key, 1, 0666)) == -1) { printf("Semaphore set does not exist!\n"); exit(1); } show_sem_usage(semset_id); return(0); } void show_sem_usage(int sid) { int cntr=0, maxsems, semval; maxsems = get_sem_count(sid); while(cntr < maxsems) { semval = semctl(sid, cntr, GETVAL, 0); printf("Semaphore #%d: --> %d\n", cntr, semval); cntr++; } } int get_sem_count(int sid) { int rc; struct semid_ds mysemds; union semun semopts; /* Получаем текущие значения для внутренней структуры данных */ semopts.buf = &mysemds; if((rc = semctl(sid, 0, IPCJ_STAT, semopts)) == -1) { perror("semctl"); exit(1); } /* Выдаем количество семафоров в множестве */ return(semopts.buf->sem_nsems); } void dispval(int sid) { int semval; semval = semctl(sid, 0, GETVAL, 0); printf("semval is %d\n", semval); }




Начало  Назад  Вперед



Книжный магазин