Описание

#include <sys/sem.h>

int semctl (int semid, int sem_num, int command, union semun ctl_arg);

Из определения видно, что функция semctl намного сложнее, чем msgctl. Па­раметр semid должен быть допустимым идентификатором семафора, возвращен­ным вызовом semget. Параметр command имеет тот же смысл, что и в вызове msgctl, - задает требуемую команду. Команды распадаются на три категории: стандартные команды управления средством межпроцессного взаимодействия (такие как IPC_STAT); команды, которые воздействуют только на один семафор; и команды, действующие на весь набор семафоров. Все доступные команды при­ведены в табл. 8.1.

Таблица 8.1. Коды функций вызова semctl

Стандартные функции межпроцессного взаимодействия
IPC_STAT Поместить информацию о статусе в поле ctl_arg.stat IPC_SET Установить данные о владельце/правах доступа IPC_RMID Удалить набор семафоров из системы
Операции над одиночными семафорами (относятся к семафору sem_num, значение возвращается вызовом semctl)
GETVAL Вернуть значение семафора (то есть setval) SETVAL Установить значение семафора равным ctl_arg.val GETPID Вернуть значение sempid GETNCNT Вернуть semncnt (см. выше) GETZCNT Вернуть semzcnt (см. выше)
Операции над всеми семафорами
GETALL Поместить значение setval в массив ctl_arg.array SETALL Установить все значения setval из массива ctl_arg.array

Параметр sem_num используется со второй группой возможных операций вы­зова semctl для задания определенного семафора. Последний параметр ctl_arg является объединением, определенным следующим образом:

union semun

{

int val;

struct semid_ds *buf;

unsigned short *array;

};

Каждый элемент объединения представляет некоторый тип значения, переда­ваемого вызову semctl при выполнении определенной команды. Например, если значение command равно SETVAL, то будет использоваться элемент ctl_arg.val.

Одно из важных применений функции setval заключается в установке на­чальных значений семафоров, так как вызов semget не позволяет процессу сделать это. Приведенная в качестве примера функция initsem может использовать­ся для создания одиночного семафора и получения связанного с ним иденти­фикатора набора семафоров. После создания семафора (если семафор еще не существовал) функция semctl присваивает ему начальное значение равное единице.

/* Функция initsem - инициализация семафора */

#include "pv.h"

int initsem(key_t semkey)

{

int status = 0, semid;

if ((semid = semget(semkey, 1, SEMPERM|IPC_CREAT|IPC_EXCL)) == -1)

{

if(errno = EEXIST)

semid = semget(semkey, 1, 0);

}

else /* Если семафор создается */

{

union semun arg;

arg.val = 1;

status = semctl(semid, 0, SETVAL, arg);

}

if(semid == -1|| status == -1)

{

perror("Ошибка вызова initsem");

return (-1);

}

/* Все в порядке */

return (semid);}

Включаемый файл pv. h содержит следующие определения:

/* Заголовочный файл для примера работы с семафорами */

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <errno.h>

#define SEMPERM 0600

#define TRUE 1

#define FALSE 0

typedef union _semun

{

int val;

struct semid_ds *buf;

ushort *array;

} semun;


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: