Linux semaphore communication example

Linux semaphore communication example

Semaphore is mainly used for process synchronization or thread synchronization, allowing one process to wait for another process to send a signal to confirm whether to perform the following operations. Only two operations are allowed to wait and send to it:
P wait for semaphore: when the semaphore sv When the value is 0, the program waits; when the semaphore sv value is greater than 0, the semaphore decreases by 1, and the program continues to run.
V send semaphore: add 1 to the value of the semaphore sv.

Header file
sys/sem.h
original function
New semaphore
int semget(key_t key,int num_sems,int sem_flags);
modify the value of the semaphore
int semop(int sem_id,struct sembuf *sem_opa,size_t num_sem_ops);
semaphore operation function, Initialize or delete
int semctl(int sem_id,int sem_num,int command,[union semun sem_union]);

Program example

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include<stdio.h>
#include<stdlib.h>
#include<sys/sem.h>

typedef union semun
{
    
    
    int val;
    struct semid_ds *buf;
    unsigned short *array;
}semun_def;

int sem_id;

int set_semvalue()
{
    
    
    semun_def sem_union;    
    sem_union.val = 1;
    if(semctl(sem_id,0,SETVAL,sem_union)==-1)
        return 0;
    return 1;
}


void sem_init()
{
    
    
	sem_id = semget((key_t)1234,1,0666|IPC_CREAT);
	 //初始化信号量
     if(!set_semvalue())
     {
    
    
         fprintf(stderr,"init failed\n");
         exit(EXIT_FAILURE);
     }
}

int sem_send(int sem_id)
{
    
    
    struct sembuf sem_b;
	
    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    if(semop(sem_id,&sem_b,1)==-1)
    {
    
    
        fprintf(stderr,"semaphore_v failed\n");
        return 0;
    }
    return 1;
}


int sem_wait(int sem_id)
{
    
    
   struct sembuf sem_b;
	
    sem_b.sem_num = 0;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    if(semop(sem_id,&sem_b,1)==-1)
    {
    
    
        fprintf(stderr,"semaphore_p failed\n");
        return 0;
    }
    return 1;
}

void sem_del(int sem_id)
{
    
    
    //删除信号量
    union semun sem_union;
    if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)
        fprintf(stderr,"Failed to delete semaphore\n");
}


//进程1
void process1(void)
{
    
    
	while(1)
	{
    
    
		printf("\n\nprocess1:send sem\n"); 
		sem_send(sem_id);
		sleep(2);
	}
}

//进程2
void process2(void)
{
    
    
	
	while(1)
	{
    
    
		printf("process2:wait sem\n"); 
		if(sem_wait(sem_id) > 0)
			printf("rcv sem\n");
	}
}

int main(int argc, const char *argv[])
{
    
    
	pid_t pid,pid1;
	
	sem_init();
	
//创建2个进程
	pid = fork(); 
	if(pid == 0)
	{
    
    
		printf("process1 create ok\n");  
		process1();
	}
	else if(pid < 0)
		{
    
    
			printf("process create failed\n"); 
			perror("fork");  
		}
		else
		{
    
    

		}
	pid1 = fork(); 
	if(pid1 == 0)
	{
    
    
		printf("process2 create ok\n");  
		process2();
	}
	else if(pid < 0)
		{
    
    
			printf("process2 create failed\n"); 
			perror("fork");  
		}
		else
		{
    
    
			
		}
 
    return 0;
}

Guess you like

Origin blog.csdn.net/u010835747/article/details/105174139