|
|
��� �������� �������� �� ��������� ������: English Castellano Deutsch Francais Italiano Nederlands Russian Turkce Polish |
����� Leonardo Giordani <leo.giordani(at)libero.it> �� ������: ������� ���������������� ������������ ������, ������ �� ����������
�������������������� ����������, �������� ������� ��������������� �
������������ ����������������� (� �������� �� ���������� � C/C++).
� 1999 ����������� ��������� �������� � Linux/Unix.
|
������:
����� ������ ����� ������ �������� ������������ �������� � ���������� ��������������� � ţ ����������� � ������������ ������� Linux. ����� � ������������� �����, �� �������� ���������� ����������� ���������, ��������������� �������������� ����� ����������, � �������, �� ����������� ���������� ������������.
��� ���������� ����� ��� ��������� ������ ������:
��� �������� ������� �������� ���������������, ��� ``�������� ���������� ���������'', �������� �� ����� �������, ��� �������� ����������� � ����� ����������� �������� �������������. ������ �������� ��� ����������� �������� �������� ������������ � �������� �������������, ������� ����� �������� ��������� ��������: ��� ������� ��������� ���������� ������ ���� ���������?
�� ����� ���� �������� ��������� ����� �������, ��� ����� ����������: ��� �� ������ ������ ������������� ������ ��������, �� ����� � ������ �������������� ������������� ����� ������, ��� ��� ������, ��� � ��� ������.
��������� � ��������� ������������ ��������� �������������� ������������� ������; ���� ��� �������� ������������ ������ ���� ����� ������, �� ���, ��������, �� ������� �������, � ���������� ��������� — ����������������. ����� ������ ���� ������� �������� ����� ������: ��������� ������ ������� �������� ����� �������� �� ����, ���ޣ� ������� ������ �� ��� ����� �� ���������. ��������: � ��� ���� ��� �������� "�" � "�" � ����� ����� "d". ������� � ����������� d �� �������, ������� � �������� �������� d. ��� ����� �������� �� �������� ����� ���:
A { d->d+1 } & B { d->output }
����� "&" �������� ������������� ���������� ���������. ������� ����� ���� �������� ������� �,(-) d = 5 (A) d = 6 (B) output = 6
� ����� � ������� �:(-) d = 5 (B) output = 5 (A) d = 6
����� �������, ��� ����� ����� ��������� ���������� � ������ ����������: ���� ���������������� ������ ����� � ����������. ���� �� �ӣ �ݣ �������������� ��� ��������, �����������, ��� ����� ������ — ��� ��� ���������� �ޣ�...� ���������� ������ �� ��� �������� � ������ ������� ������������� --- ������������� ������� waitpid(2), ����������� �������� ��������� ���������� ������� ��������, ����������� �� ��� �� ������ ������, � ������ ����� ���������� ���� ������.
��������, ��� �� ����� ������ ������: ������� �������� ����������� � �������� ���������� ������ ������ ���������. ������������ ����������� � ���, ��� ������ ������� ����� �������� �������� �����, � ������ ������� ������������ ������ �������� ���������� �������. ����� �������, ��� ���������� ��������� "�����������������" ������ ����������, �.�. ��������� ���������� �������� ������. ������� ������ �������� — ��������� �� ����������� ����������, ��������� ��� SysV IPC (�������������� ��������� � System V).
key_t ftok(const char *pathname, int proj_id);
��� ������������� ����� ftok ��ң� ��� ������������� ����� (pathname) � ������������� �������� (proj_id). �������� ���������� ����� �� ��������� ����������� ��������� ����������, ������� ������� ����� ��������� ����������, ��������������� ��� ��������� ����� � �� ����������� ����������.�������� ����� �������������� ��� ��������������� ������� � ��������: ����� � �������� ������������ ����� ���������� ���������, ������� ����� �������� ������ � ������. ������ ���, ����� ������� ���������� � ������, �������� � ��������, ������ ���� ��������� �� �������, � ���������, ����� ������ � ������� ����� ����������. ���� ������ ������������, �� ���� � ������ ������ ����� ������ ������ ���� �������, �� ��������� �������� � �������� ������� ���������� ��������.
�������� ����� ������������ � ��� ������ �����, �������� ��� �ޣ����� ��������. � ���� ������ ����� � �������� — ���������� ��������� �������� (�������� ���������� ��������� ����� ������).
���������� ������������ ���������� ���������. ����� � ��� ���� �����, � ������� ��������� ��������� S1,...,Sn ����� ������, � ������ ���� ������� L ����� �� ���� ������. ����� �������� ������ ��������� ������������ (� ������ ������ ������� ������ ���� ������� ������ ����������� � �������). ��������, ��� �������� Si ����� ������ ������, ����� ����� �� �����, � ������� L ����� ������, ����� ����� �� ����. ����� �������, ��� ���������� ��� ��������: ���� ��������� �������� � ������, � ��� ������ ������ �� ������ ��������� � �.
��������, ��� ������ � ������ ������ ���� ������������, ������ ������� ����� �������� (��� �������� ����� ��̣� ��� ��������), � �� ����� ��� ������ � ������ ����� ��������� ��������, ��������� �� ������� ������.
����������, ��� ����������� �������� �� C, � SysV. ������� ������� ������� semget(2)
int semget(key_t key, int nsems, int semflg);
����� key — IPC ����, nsems — ����� ���������, ������� �� ����� �������, � semflg — ����� �������, �������������� � 12 ���: ������ ��� ���� �������� �� ����� ��������, ��������� ������ — ����� �� ������ � ������ ��� ������������, ������ � ��������� (�������� �������� � �������� �������� � Unix). �� ����� ������ ����������� ��������� � man �������� ipc(5). ��� �� ������ SysV ������� ����� ��������� ���������, ��� ��������� ���.������� �������� ��� ������ �������
#include <stdio.h> #include <stdlib.h> #include <linux/types.h> #include <linux/ipc.h> #include <linux/sem.h> int main(void) { key_t key; int semid; key = ftok("/etc/fstab", getpid()); /* ������� ������ ���� �������: */ semid = semget(key, 1, 0666 | IPC_CREAT); return 0; }����� ��� ���� �������� ��� ��������� ����������, � ��� ������� ��. ���������� ���������� � ������� ������� semctl(2),
int semctl(int semid, int semnum, int cmd, ...)
������� ��������� �������� cmd �� ������ ��������� semid ��� (���� ��������� ��������) �� ����� �������� � ������� semnum. �� ��������� � ��������� ��� �������, ����� ������ ����������, ������ �� ������ ������� �������� �� man ���������. � ����������� �� �������, ����� ����������� ������� �ݣ ���� �������� ���������� ����:union semun { int val; /* �������� ��� SETVAL */ struct semid_ds *buf; /* ������ ��� IPC_STAT, IPC_SET */ unsigned short *array; /* ������� ��� GETALL, SETALL */ /* �����, ��������� ��� Linux: */ struct seminfo *__buf; /* ����� ��� IPC_INFO */ };����� �������� �������� ��������, ���������� ��������� SETVAL, ����� �������� ������ ���� ������� � semun; ������� ������������ �����ģ���� ���� ���������, ������������ � �������� �������� 1.
[...] /* ������� ������ ���� ������� */ semid = semget(key, 1, 0666 | IPC_CREAT); /* � �������� 0 ���������� �������� 1 */ arg.val = 1; semctl(semid, 0, SETVAL, arg); [...]������ ���������� ������� �������, ���������� ���������, ���������������� ��� ���������� ��; ��� ��������� ��������� IPC_RMID. ��� ������� ������� � �������� ��������� �� ���� ���� ���������, ��������� ������� � �������. ��������� ��� ������� ���������:
[...] /* � �������� 0 ���������� �������� 1 */ arg.val = 1; semctl(semid, 0, SETVAL, arg); /* ������� ������� */ semctl(semid, 0, IPC_RMID); [...]��� �� ��� ������, �������� � ���������� ����������� �������� �� ������������ ����������� �������� ���������� ������, ����� �� ������� ��������� ������, �ӣ ������ ��������� ����� ������, �� ������ � ������ ��������� ����.
������������ ������� ����� � ������� ��������� semop(2),
int semop(int semid, struct sembuf *sops, unsigned nsops);
����� semid — ������������� ������ ���������, sops — ������, ���������� ��������, ������� ���������� ����������, nsops — ����� ���� ��������. ������ �������� �������������� ���������� sembuf.unsigned short sem_num; short sem_op; short sem_flg;
�.� ������� �������� � ��������� (sem_num), ��������� (sem_op) � ������, ��������������� ����� ��������; ����� ���� �� ����� ��̣�. ��������, ������� �� ����� �������, �������� ������ ������� � ����������� ��������� ��������:������ � ������ � ����� �� ����� ���� �����������: ��� ���������� ������, ���, ��� ����������� � ���������� ������, ������ ������� ����������� � ��ϣ� ����������� ������� ������ � �� ����� ���������� � ������ ������� ��������. ��� ������ ��������� ���������� ������� ������ ���������� �����������, ��� ��� ������ ������� ����� ������ ���� ����� ������. �ӣ ������� �� ���� �����, ����� �� ����� �������� � ����������� ������, �� ������� ���� �����������������.
������ ��� ����� ��� ��������? ������ (� ������� 0) ��������� ��� ����� � ������, � ��� ������������ �������� ����� �������, ��������� ��� �������� �� ������������ � ������� ��������� � ������. ����� ��������� ����� �� ��������.
����������� � ���� ��������� ������� � ������������ ������ ������� semop. ����, ��������, �������� W ��������� �������� � ��������, ���������� �� ��������� ����� � ������, �� ����, �� ������� R ����� ����������� ��� �������� �� �������������. ������� ����� ������� �� ����� ��������� �� ���������� ��������� � ������.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <linux/types.h> #include <linux/ipc.h> #include <linux/sem.h> int main(int argc, char *argv[]) { /* IPC */ pid_t pid; key_t key; int semid; union semun arg; struct sembuf lock_res = {0, -1, 0}; struct sembuf rel_res = {0, 1, 0}; struct sembuf push[2] = {1, -1, IPC_NOWAIT, 2, 1, IPC_NOWAIT}; struct sembuf pop[2] = {1, 1, IPC_NOWAIT, 2, -1, IPC_NOWAIT}; /* ��������� */ int i; if(argc < 2){ printf("Usage: bufdemo [dimensione]\n"); exit(0); } /* �������� */ key = ftok("/etc/fstab", getpid()); /* ������� ����� �� �ң� ��������� */ semid = semget(key, 3, 0666 | IPC_CREAT); /* ���������� � �������� ����� 0 (���������� ��������) �������� "1" */ arg.val = 1; semctl(semid, 0, SETVAL, arg); /* ���������� � �������� ����� 1 (���������� ���������� �����) �������� ����� ������ */ arg.val = atol(argv[1]); semctl(semid, 1, SETVAL, arg); /* ���������� � �������� ����� 2 (���������� ��������� � ������) �������� "0" */ arg.val = 0; semctl(semid, 2, SETVAL, arg); /* Fork */ for (i = 0; i < 5; i++){ pid = fork(); if (!pid){ for (i = 0; i < 20; i++){ sleep(rand()%6); /* ���������� ������������� ������ (������� ����� 0) */ if (semop(semid, &lock_res, 1) == -1){ perror("semop:lock_res"); } /* ��������� ��������� ����� (������� ����� 1) / �������� ������� (������� ����� 2) */ if (semop(semid, &push, 2) != -1){ printf("---> Process:%d\n", getpid()); } else{ printf("---> Process:%d BUFFER FULL\n", getpid()); } /* �������������� ������ */ semop(semid, &rel_res, 1); } exit(0); } } for (i = 0;i < 100; i++){ sleep(rand()%3); /* ���������� ������������� ������ (������� ����� 0)*/ if (semop(semid, &lock_res, 1) == -1){ perror("semop:lock_res"); } /* ��������� ��������� ����� (������� ����� 1) / ����� ������� (������� ����� 2) */ if (semop(semid, &pop, 2) != -1){ printf("<--- Process:%d\n", getpid()); } else printf("<--- Process:%d BUFFER EMPTY\n", getpid()); /* �������������� ������ */ semop(semid, &rel_res, 1); } /* ������� �������� */ semctl(semid, 0, IPC_RMID); return 0; }��������������� �������� ���������� ����� ����:
struct sembuf lock_res = {0, -1, 0}; struct sembuf rel_res = {0, 1, 0}; struct sembuf push[2] = {1, -1, IPC_NOWAIT, 2, 1, IPC_NOWAIT}; struct sembuf pop[2] = {1, 1, IPC_NOWAIT, 2, -1, IPC_NOWAIT};��� ������ ������ — ��������, ������� �� ����� ����������� ��� ����������: ������ ��� — �������� �� ������ �������� ������, ������ — �� ���. ������ ��������, lock_res, ��������� ������: ��� ��������� �������� ������� (����� 0) �������� �� ������� (���� �������� � �������� �� ����), � ���� ������ ��� �����, �� ������� �ģ�. �������� rel_res ���������� lock_res, ������ �������� � ������ �������� ������������� �� �������, �.�. ��������� ���������� �������.
�������� push � pop ��������� ���������� �� ������: ��� ������� �� ���� ��������. ������ �������� ��� ��������� ����� 1, ������ — ��� ��������� ����� 2; ���� ����������� �������� � ��������, ������ ���������, �� ������ ������� �� ����� ����� ������������ �������: IPC_NOWAIT ���������� ��� ���������� ������, ���� ������ ������������.
/* ���������� � �������� ����� 0 (���������� ��������) �������� "1" */ arg.val = 1; semctl(semid, 0, SETVAL, arg); /* ���������� � �������� ����� 1 (���������� ���������� �����) �������� ����� ������ */ arg.val = atol(argv[1]); semctl(semid, 1, SETVAL, arg); /* ���������� � �������� ����� 2 (���������� ��������� � ������) �������� "0" */ arg.val = 0; semctl(semid, 2, SETVAL, arg);����� �� �������������� �������� � ���������: � ������ — ��������, ��� ��� �� ������������ ������ � �������, �� ������ — ������ ������ (�������� � ��������� ������), � ������� — ��̣� (�.�. ������ ��������� � ������).
/* ���������� ������������� ������ (������� ����� 0) */ if (semop(semid, &lock_res, 1) == -1){ perror("semop:lock_res"); } /* ��������� ��������� ����� (������� ����� 1) / �������� ������� (������� ����� 2) */ if (semop(semid, &push, 2) != -1){ printf("---> Process:%d\n", getpid()); } else{ printf("---> Process:%d BUFFER FULL\n", getpid()); } /* ���������� ������ */ semop(semid, &rel_res, 1);������� W �������� ������������� ������ ����������� �������� lock_res; ��� ������ ��� ��� �������, �� ��������� ������� � ����� ����������� �������� push � ������� ��������� �� ���� �� ����������� �����. ���� �������� �� ����� ���� �����������, ������� ������� ��������� � ���������� ������. � ����� ������� ����������� ������.
/* ���������� ������������� ������ (������� ����� 0) */ if (semop(semid, &lock_res, 1) == -1){ perror("semop:lock_res"); } /* ��������� ��������� ����� (������� ����� 1) / ����� ������� (������� ����� 2) */ if (semop(semid, &pop, 2) != -1){ printf("<--- Process:%d\n", getpid()); } else printf("<--- Process:%d BUFFER EMPTY\n", getpid()); /* ��������� ������ */ semop(semid, &rel_res, 1);������� R ��ģ� ���� ����������� ��� �� ��� � W �������: ��������� ������, ���������� �������� pop, ����������� ������.
� ��������� ������ �� ��������� �� �������� ���������: ������ ��������� ��� ��������������� ������� � �������������. ��� ������, ���� �� ������ ���-������ �������, ��������� ���������� �� ���� ������, ���������� ��� ���, � ����� ������ � e-mail �������, ���� ��� ���������. �����!
|
Webpages maintained by the LinuxFocus Editor team
© Leonardo Giordani, FDL LinuxFocus.org |
Translation information:
|
2003-02-06, generated by lfparser version 2.31