ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

02 | linux下进程同步(信号量实现)

2022-04-20 11:33:43  阅读:215  来源: 互联网

标签:02 进程同步 int void 信号量 参数 semaphore sem


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include <sys/sem.h>

/*程序目的:
1、完成两个进程的同步
2、每个进程进入临界区后输出一对字符
3、主进程输出‘X',其余进程输出'O'
4、主进程负责创建和销毁信号量
*/
/*收获
1、深刻理解信号量是一种资源。它同样可以像文件那样指定key键值
2、同一个信号量(文件)key在不同的程序中被打开得到单属于该文件的“标识符”
3、创建信号量的同时需要指定权限
*/

//该union为程序员自己写的,当然有的linux系统也是可以提供的
union semun{
	int val;
};

static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);

static int sem_id;	//信号量标识符

int main(int argc,char *argv[])
{
	int i;
	int pause_time;
	char op_char = '0';

	srand((unsigned int)getpid());
	
	//第一个参数key_t相当于文件名,
	//第二个参数1代表指定需要的信号量数目它几乎总是1;
	//第三个参数为打开信号量的权限和标志。ipc_creat就算打开一个已有的信号量也不会错误
	sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);
	
	//主线程才会执行的代码负责信号量的创建
	if (argc > 1) {
		if (!set_semvalue()) {
			fprintf(stderr, "failed to \ 
				initialize semaphore\n");
				exit(EXIT_FAILURE);
		}
		op_char = 'X';
		sleep(2);
	}
	
	for (i = 0; i < 10; i++) {
		//进程临界区
		if (!semaphore_p()) exit(EXIT_FAILURE);
		printf("%c", op_char); fflush(stdout);
		pause_time = rand() % 3;
		sleep(pause_time);
		printf("%c", op_char); fflush(stdout); //打印成对的字符
		//退出临界区
		if (!semaphore_v()) exit(EXIT_FAILURE);
		pause_time = rand() % 2;
		sleep(pause_time);
	}
	printf("\n%d-finished\n", getpid());
	//由主进程负责销毁信号量
	if (argc > 1) {
		sleep(10);
		del_semvalue();
	}
	exit(EXIT_SUCCESS);
}
static int set_semvalue(void) {
	union semun sem_union; //控制信号量的初始化和销毁

	sem_union.val = 1;  //信号量的最大值为1
	//semctl函数负责用来直接控制信号量信息。即初始化和销毁
	//第一个参数
	//第二个参数为信号量的个数,一般取值为0
	//第三个参数代表初始化
	//第四个参数为响应第三个参数:提供初始化值
	if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return 0;
	return 1;
}
static void del_semvalue(void) {
	union semun sem_union;
	//semctl函数负责用来直接控制信号量信息。即初始化和销毁
	//第一个参数
	//第二个参数为信号量的个数,一般取值为0
	//第三个参数代表销毁
	//第四个参数为响应第三个参数:提供初始化值
	if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
		fprintf(stderr, "failed to delete semaphore\n");
}
static int semaphore_p(void) {
	struct sembuf sem_b;
	sem_b.sem_num = 0; //对第几个信号进行操作,我们只有一个
	sem_b.sem_op = -1;//P()
	sem_b.sem_flg = SEM_UNDO;//标识符:进程没有释放信号量终止则OS负责回收
	//semop函数负责改变信号量的值
	//第一个参数是信号量标识符
	//第二个参数是指向一个结构数组的指针
	//第三个参数为第二个参数的补充,数组内的元素
	if (semop(sem_id, &sem_b, 1) == -1) {
		fprintf(stderr, "semaphore_p failed\n");
		return 0;
	}
	return 1;
}
static int semaphore_v(void) {
	struct sembuf sem_b;
	sem_b.sem_num = 0;
	sem_b.sem_op = 1;//V()
	sem_b.sem_flg = SEM_UNDO;
	if (semop(sem_id, &sem_b, 1) == -1) {
		fprintf(stderr, "semaphore_vfailed\n");
		return 0;
	}
	return 1;
}

标签:02,进程同步,int,void,信号量,参数,semaphore,sem
来源: https://www.cnblogs.com/mmxingye/p/16169081.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有