[LinuxFocus-icon]
�����  |  �����  |  ������  |  �����

������� | ������ | ������ | ��� LF
��� �������� �������� �� ��������� ������: English  Castellano  Deutsch  Francais  Italiano  Nederlands  Russian  Turkce  Polish  

[Leonardo]
����� Leonardo Giordani
<leo.giordani(at)libero.it>

�� ������:

������� ���������������� ������������ ������, ������ �� ���������� �������������������� ����������, �������� ������� ��������������� � ������������ ����������������� (� �������� �� ���������� � C/C++). � 1999 ����������� ��������� �������� � Linux/Unix.

������� �� �������:
Dmitry Martsynkevitch <ursa(at)zaba.ru>

����������:


 

������������ ���������������� — �������������� ����� ����������.

[run in paralell]

������:

����� ������ ����� ������ �������� ������������ �������� � ���������� ��������������� � ţ ����������� � ������������ ������� Linux. ����� � ������������� �����, �� �������� ���������� ����������� ���������, ��������������� �������������� ����� ����������, � �������, �� ����������� ���������� ������������.

��� ���������� ����� ��� ��������� ������ ������:

����� ��� ������� ��������� ������ ������ �� ����� �����, ��������� ��� �������� ������� ��� ������: November 2002, article 272.
_________________ _________________ _________________

 

��������

�� ��� � ����� �� ������� � ����������������� � 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).  

����� SysV

������ ��� ������� � ����� ������ ���������������, ������� ������������ � �������� SysV ����������: IPC �������. IPC ���� — ��� �����, ���������� ���������������� IPC ��������� ���������� (����������� ����). ����� ���� ����� ������������ ��� ����������� ������������� ���������������, �.�. ��� ����������� �� IPC ��������. ���� ��������� �������� ftok(3).

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) � ������, ��������������� ����� ��������; ����� ���� �� ����� ��̣�. ��������, ������� �� ����� �������, �������� ������ ������� � ����������� ��������� ��������:
  1. sem_op < 0
    ���� ������ �������� � �������� ������ ��� ����� ������ sem_op, �� sem_op ����������� � �������� � �������� (�.�. �������� � �������� �����������). ���� ������ sem_op ������, �� ������� ��������� � ������ �����, ���� �� ����� ���������� ��������.
  2. sem_op = 0
    ������� ���� ���� �������� � �������� �� ��������� ����.
  3. sem_op > 0
    �������� sem_op ����������� � �������� � ��������, ������������ ������ �������������.
��������� ��������� ������������ ������ ������������� ���������, �������� ���������� ������ � �������: �� �������� ���� ��������� W � ���� ������� R. �������� W ����� �������� �������� ������ � ������� (������), �������� ��� ����� �������, �, ���� ����� �� �����, ����� ������ � ���� ������� � ����������� ������. ������� R ����� ��������� ������, ����� �� ���� �������, ���� ����� �� ����, � �������������� ������.

������ � ������ � ����� �� ����� ���� �����������: ��� ���������� ������, ���, ��� ����������� � ���������� ������, ������ ������� ����������� � ��ϣ� ����������� ������� ������ � �� ����� ���������� � ������ ������� ��������. ��� ������ ��������� ���������� ������� ������ ���������� �����������, ��� ��� ������ ������� ����� ������ ���� ����� ������. �ӣ ������� �� ���� �����, ����� �� ����� �������� � ����������� ������, �� ������� ���� �����������������.

������ ��� ����� ��� ��������? ������ (� ������� 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 �������, ���� ��� ���������. �����!  

������������� ����������

 

�������� �������

� ������ ������� ���� �������� �������. �� ���� �������� �� ������ �������� ���� ����������� ��� ����������� ����������� ������ ��������� :
 talkback page 

Webpages maintained by the LinuxFocus Editor team
© Leonardo Giordani, FDL
LinuxFocus.org
Translation information:
it --> -- : Leonardo Giordani <leo.giordani(at)libero.it>
it --> en: Leonardo Giordani <leo.giordani(at)libero.it>
en --> ru: Dmitry Martsynkevitch <ursa(at)zaba.ru>

2003-02-06, generated by lfparser version 2.31