Programación del sistema Linux 65 procesos, comunicación entre subprocesos Matriz de 3 semáforos

NAME
       semget - get a System V semaphore set identifier :
创建一个新的信号量或获取一个已经存在的信号量的ID

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>

/ *
clave:
Si la creación y adquisición del proceso no relacionado es la misma que la cola de mensajes anterior.
Si en el proceso relacionado, después de fork (), cada proceso hijo puede obtener el valor de clave creado por el proceso padre. En este momento , ya no le importa el valor de la clave. En este momento, puede configurarlo en IPC_PRIVATE, lo que significa que el IPC es un IPC anónimo y no requiere ftok.

nsems: especifique cuántos elementos en la matriz de semáforos actual
semflg: otros requisitos especiales, cuando la clave es IPC_PRIVATE, semflg se establece en IPC_CREAT

* /

int semget(key_t key, int nsems, int semflg);


RETURN VALUE
       If successful, the return value will be the semaphore set identifier (a nonnegative integer), otherwise, -1 is returned, with errno indicating the error.

NAME
       semctl - System V semaphore control operations 
		对目标信号量执行各类操作,不过最常用的是删除它。
SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>

/ *
semid: IPC ID
semnum: el valor del subíndice del semáforo de destino en la matriz
cmd: comando

...
IPC_RMID:从系统中删除目标信号量集合
......
SETVAL:设置数组中下标为semnum的成员值,即设置某个信号量的资源量
......

最后参数:初始值,即资源总量


//设置ID为semid的信号量集合数组中 第1个信号量的资源总量为1
semctl(semid,0,SETVAL,1):

* /

   int semctl(int semid, int semnum, int cmd, ...);

VALOR DEVUELTO
En caso de error, semctl () devuelve -1 con errno indicando el error.
De lo contrario, la llamada al sistema devuelve un valor no negativo dependiendo de cmd de la siguiente manera:


colección de semáforos de operación semop ()

NAME
       semop, semtimedop - System V semaphore operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>

	/*
semid:目标IPC ID
sops :结构体数组地址
nsops:每个结构体大小
*/
       int semop(int semid, struct sembuf *sops, size_t nsops);

Los elementos de esta estructura son de tipo struct sembuf y contienen los siguientes miembros:

		信号量编号,当使用单个信号量时候,为0
       unsigned short sem_num; 
       信号量操作,取值为-1,表示P操作。归还为+1,为释放操作
       short          sem_op;  
       short          sem_flg;  /* operation flags */

VALOR DEVUELTO
Si tiene éxito, semop () y semtimedop () devuelven 0; de lo contrario, devuelven -1 con errno indicando el error.

ERRORES
En caso de error, errno se establece en uno de los siguientes:

   E2BIG  The argument nsops is greater than SEMOPM, the maximum number of operations allowed per system call.

   EACCES The calling process does not have the permissions required to perform the specified semaphore operations, and does not have the CAP_IPC_OWNER capability.

   EAGAIN 假错

   EFAULT An address specified in either the sops or the timeout argument isn't accessible.

   EFBIG  For some operation the value of sem_num is less than 0 or greater than or equal to the number of semaphores in the set.

   EIDRM  The semaphore set was removed.

   EINTR  While blocked in this system call, the thread caught a signal; see signal(7).

   EINVAL The semaphore set doesn't exist, or semid is less than zero, or nsops has a nonpositive value.

   ENOMEM The sem_flg of some operation specified SEM_UNDO and the system does not have enough memory to allocate the undo structure.

   ERANGE For some operation sem_op+semval is greater than SEMVMX, the implementation dependent maximum value for semval.

Experimento: uso de semáforo, 20 procesos escriben el mismo archivo, solo hay un semáforo en el conjunto de semáforos en esta rutina, y su función es similar a la de un mutex.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define PROCNUM 20
#define FNAME "/home/mhr/Desktop/xitongbiancheng/super_io/out"
#define LINESIZE 1024
static 	int semid;

//取资源量
static void P(void)
{
	struct sembuf op;
	
	op.sem_num = 0;
	op.sem_op = -1;
	op.sem_flg = 0;

	while(semop(semid,&op,1) < 0)
	{
		if(errno != EINTR || error != EAGAIN)
		{
			perror("semop()");
			exit(1);
		}
	}
}

//归还资源量
static void V(void)
{
	struct sembuf op;
	
	op.sem_num = 0;
	op.sem_op = -1;
	op.sem_flg = 0;

	if(semop(semid,&op,1) < 0)
	{
		perror("semop()");
		exit(1);

	}
}

static void func_add(void)
{
	FILE *fp;
	int fd;
	char linebuf[LINESIZE];

	fp = fopen(FNAME,"r+");
	if(fp == NULL)
	{
		perror("fopen()");
		exit(1);
	}



P();//取资源量
	fgets(linebuf,LINESIZE,fp);
	fseek(fp,0,SEEK_SET);

	//sleep(1);	
	
	fprintf(fp,"%d\n",atoi(linebuf)+1);
	fflush(fp);
V();//归还资源量
	
	fclose(fp);
return;

} 

int main()
{
	int i,err;
	pid_t pid;

//创建信号量数组 IPC 返回值为id
	semid = semget(IPC_PRIVATE,1,IPC_CREAT);
	if(semid < 0)
	{
		perror("semget");
		exir(0);
	}

// 设置信号量集合中 第一个信号量的资源总量为1
	if(semctl(semid,0,SETVAL,1) < 0)
	{
		perror("semctl");
		exir(0);	
	}

	for(i = 0; i < PROCNUM; i++)
	{
		pid = fork();
		if(pid < 0)
		{
			perror("fork()");
			exit(1);
		}
		
		if(pid == 0)//Child 
		{
			func_add();
			exit(0);
		}

	}


	for(i = 0;i < PROCNUM; i++)
	{
		wait(NULL);
	}
	
	//从当前系统 删除该 信号量集合
	semctl(semid,0,IPC_RMID);

	exit(0);
	
}

Supongo que te gusta

Origin blog.csdn.net/LinuxArmbiggod/article/details/114849643
Recomendado
Clasificación