使用信号量进行进程间的互斥

 

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

union semun
{
	int val;
	struct semid_ds *buf;
	unsigned short int *array;
	//struct seminfo * __buf;
};


static int init_sem( int id );
static int close_sem( int id );
static int sem_p( int id );
static int sem_v( int id );
int main( int argc , char *argv[] )
{
	char *message = "X";
	int sem_id = 0;
	sem_id = semget( (key_t)1234, 1, 0666 | IPC_CREAT );
	printf("sem_id = %d\n" , sem_id);
	if( argc > 1 )
	{
		if( init_sem( sem_id ) == 0 )
		{
			printf("sem init error return!\n");
			exit(1);
		}
		message = argv[1];
	}
	while(1)
	{
		if( sem_p( sem_id ) == -1 )
		{
			exit(1);
		}
		
		printf("%s\n" , message);
		sleep(rand() % 3);		
		printf("%s\n" , message);
		
		if( sem_v( sem_id ) == -1 )
		{
			exit(1);
		}
		sleep( rand() %3 );
	}
	
	if( argc > 1 )
	{
		close_sem( sem_id );
	}
	
	return 0;
}

static int init_sem( int id )
{
	union semun sem_union;
	sem_union.val = 1;
	if( semctl( id, 0, SETVAL, sem_union ) == -1 )
	{
		printf(" semctl:%s\n" , strerror(errno));
		return 0;
	}
	return 1;
}

static int close_sem( int id )
{
	if( semctl( id, IPC_RMID, 0 ) == -1 )
	{
		printf("delete sem error!\n");
		return 0;
	}
	return 1;
}

static int sem_p( int id )
{
	//-1 wait for p
	struct sembuf sem_buf;
	sem_buf.sem_num = 0;
	sem_buf.sem_op = -1;
	sem_buf.sem_flg = SEM_UNDO;

	if( semop( id, &sem_buf, 1 ) == -1 )
	{
		printf(" semop:%s\n" , strerror(errno));
		printf("sem_p set error!\n");
		return -1;
	}
	return 1;
}

static int sem_v( int id )
{
	//1 send singal v
	struct sembuf sem_buf;
	sem_buf.sem_num = 0;
	sem_buf.sem_op = 1;
	sem_buf.sem_flg = SEM_UNDO;

	if( semop( id, &sem_buf, 1 ) == -1 )
	{
		printf(" semop:%s\n" , strerror(errno));
		printf("sem_v set error!\n");
		return -1;
	}
	return 1;
}

参考:https://blog.csdn.net/ljianhui/article/details/10243617

以上代码为改正后的代码。

实验结果和参考的博客一致,功能相当于两个进程之间的互斥锁。

出现的问题:

1.semctl函数报错:numerical result out of range

原因是原来的代码子进程的运行流程没有semget,导致传给semctl的id是0,超出范围。

2.semop函数报错:Invalid argument,同理也是因为id号为0导致非法参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
进程信号量通信是操作系统实验中常用的一种进程通信方式。信号量是一个计数器,用于控制多个进程对共享资源的访问。在操作系统实验中,我们通常使用二进制信号量semaphore)来实现进程互斥与同步。 在一个典型的实验中,我们可以利用信号量来实现生产者-消费者问题的解决方案。首先,我们创建一个共享缓冲区作为生产者和消费者之的通信通道。然后,我们创建两个进程,一个是生产者进程,另一个是消费者进程。这两个进程通过信号量进行同步与互斥。 生产者进程负责向共享缓冲区中生产数据,而消费者进程负责从共享缓冲区中消费数据。在进程进行相应操作之前,它们需要通过信号量来判断是否可以执行。如果生产者进程发现共享缓冲区已满,则需要等待信号量的值变为一个非零值。而如果消费者进程发现共享缓冲区为空,则需要等待信号量的值变为一个非零值。 当生产者进程完成数据的生产后,它需要减少信号量的值,表示数据已经被生产出来。而当消费者进程完成数据的消费后,它也需要减少信号量的值,表示共享缓冲区中的数据已经被消费掉。通过这种方式,我们可以确保生产者和消费者之的数据传递是有序且互斥的。 在操作系统实验中,我们可以使用C语言的系统调用或者库函数来创建和操作信号量。例如,可以使用semget()来创建信号量使用semop()来对信号量进行操作,包括增加、减少和等待等。 总之,进程信号量通信是一种非常重要的进程通信方式,在操作系统实验中常常被用于解决共享资源的互斥与同步问题。它的使用可以保证进程的顺序执行以及避免竞态条件。通过灵活地运用信号量,可以实现更为复杂的进程通信应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值