При использовании setpgid() pgid
должна быть группой существующего процесса, которая является частью текущего сеанса, фактически подключая pid
к этой группе процессов. В противном случае pgid
должна равняться pid
, создавая новую группу процессов.
Имеется несколько значений для особых случаев как для pid
, так и для pgid
:
pid = 0
В данном случае setpgid()
изменяет группу процессов вызывающего процесса на pgid
. Это эквивалентно 'setpgid(getpid(), pgid)
'.
pgid = 0
Это устанавливает ID группы процессов для данного процесса равным его PID. Таким образом, 'setpgid(pid, 0)
' является тем же самым, что и 'setpgid(pid, pid)
'. Это делает процесс с PID, равным pid
, лидером группы процессов.
Во всех случаях лидеры сеанса являются особыми; их PID, ID группы процессов и ID сеанса идентичны, a ID группы процессов лидера не может быть изменена. (ID сеанса устанавливаются посредством setsid()
, а получаются посредством getsid()
. Это особые вызовы: см. справочные страницы
9.3. Базовое межпроцессное взаимодействие: каналы и очереди FIFO
9.3.1. Каналы
Каналы проявляют себя как обычные дескрипторы файлов. Без особого разбирательства вы не можете сказать, представляет ли дескриптор файла сам файл или канал. Это особенность; программы, которые читают из стандартного ввода и записывают в стандартный вывод, не должны знать или заботиться о том, что они могут взаимодействовать с другим процессом. Если хотите знать, каноническим способом проверки этого является попытка выполнить с дескриптором 'lseek(fd, 0L, SEEK_CUR)
'; этот вызов пытается отсчитать 0 байтов от текущего положения, т е. операция, которая ничего не делает[94]. Эта операция завершается неудачей для каналов и не наносит никакого вреда другим файлам.
9.3.1.1. Создание каналов
Системный вызов pipe()
создает канал:
#include
int pipe(int filedes[2]);
Значение аргумента является адресом массива из двух элементов целого типа, pipe()
возвращает 0 при успешном возвращении и -1, если была ошибка.
Если вызов был успешным, у процесса теперь есть два дополнительных открытых дескриптора файла. Значение filedes[0]
является filedes [1]
—
Как упоминалось, данные, записанные в записываемый конец, считываются из читаемого конца. После завершения работы с каналом оба конца закрываются с помощью вызова close()
. Следующая простая программа, ch09-pipedemo.c
, демонстрирует каналы путем создания канала, записи в него данных, а затем чтения этих данных из него:
1 /* ch09-pipedemo.c --- демонстрация ввода/вывода с каналом. */
2
3 #include
4 #include
5 #include
6
7 /* main --- создание канала, запись в него и чтение из него. */
8
9 int main(int argc, char **argv)
10 {
11 static const char mesg[] = "Don't Panic!"; /* известное сообщение */
12 char buf[BUFSIZ];
13 ssize_t rcount, wcount;
14 int pipefd[2];
15 size_t l;
16
17 if (pipe(pipefd) < 0) {
18 fprintf(stderr, "%s: pipe failed: %s\n", argv[0],
19 strerror(errno));
20 exit(1);
21 }
22
23 printf("Read end = fd %d, write end = fd %d\n",
24 pipefd[0], pipefd[1]);
25
26 l = strlen(mesg);
27 if ((wcount = write(pipefd[1], mesg, 1)) != 1) {
28 fprintf(stderr, "%s: write failed: %s\n", argv[0],
29 strerror(errno));
30 exit(1);
31 }
32