Linux信号量+共享内存(有名,非匿名)使用示例

信号量+(有名,非匿名)共享内存使用示例:

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

#define MAX_SIZE 4096

union semun {
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO
							   (Linux-specific) */
};

enum KEY_STAT{
	NONE,
	KEY_ON,
	KEY_OFF,
};

struct wdt_share_mem{
	unsigned int timeleft;  //单位:秒
	enum KEY_STAT key_stat;
};

struct wdt_private_data{
	key_t key;
	int shmid;
	int semid;
	union semun union_sem;
	struct wdt_share_mem *wdt_shm;
	
};

static int sem_p(int id)
{
	int ret;
	struct sembuf buf;
	
	buf.sem_num = 0;
	buf.sem_op = -1;
	buf.sem_flg = SEM_UNDO;
	ret = semop(id, &buf, 1);
	if(-1 == ret){
		syslog(LOG_USER|LOG_ERR, "semop");
		return -1;
	}
	return 0;
}

static int sem_v(int id)
{
	int ret;
	struct sembuf buf;
	
	buf.sem_num = 0;
	buf.sem_op = 1;
	buf.sem_flg = SEM_UNDO;
	ret = semop(id, &buf, 1);
	if(-1 == ret){
		syslog(LOG_USER|LOG_ERR, "semop");
		return -1;
	}
	return 0;
}

int wdt_init(struct wdt_private_data *priv)
{
	int ret = 0;
	
	priv->key = ftok("/dev/null", 'p');
/* 信号量申请 */
	priv->semid = semget(priv->key, 1, IPC_CREAT);
	if(-1 == priv->semid){
		syslog(LOG_USER|LOG_ERR, "semget");
		return -1;
	}
/* 信号量初始化 */
	priv->union_sem.val = 1;
	ret = semctl(priv->semid, 0, SETVAL, priv->union_sem);
	if(-1 == ret)
	{
		syslog(LOG_USER|LOG_ERR, "semctl");
		return -1;
	}
/* 共享内存申请 */
	priv->shmid = shmget(priv->key, MAX_SIZE, 0666 | IPC_CREAT);
	if(priv->shmid == -1){
		syslog(LOG_USER|LOG_ERR, "wdt shm get error!");
		return -1;
	}
	priv->wdt_shm = (struct wdt_share_mem *)shmat(priv->shmid, NULL, 0);
/* 共享内存初始化 */
	priv->wdt_shm->timeleft = 0;  //初始化时间,单位:秒
	priv->wdt_shm->key_stat = NONE;  //按键键值状态,未定义
	
	return ret;
}

int main(int argc,char *argv[])
{
	int ret;
	struct wdt_private_data *wdt_priv;
	unsigned int secleft;
	
	if(ret = daemon(0, 0)){  //参数1 =0:工作目录将被设置为“/”(根目录),
							//参数2 =0:标准输入、标准输出和标准错误输出都被重定向到/dev/null文件
		perror("wdt change to daemon err");
		exit(-1);
	};
	
	wdt_priv = (struct wdt_private_data *)malloc(sizeof(struct wdt_private_data));
	if(wdt_priv == NULL){
		syslog(LOG_USER|LOG_ERR, "wdt malloc error!");
		exit(-1);
	}
	
	if((ret = wdt_init(wdt_priv)) < 0){
		exit(-1);
	}
	
	system("echo 0 > ./a.txt");  //do something
	for(;;){
		sem_p(wdt_priv->semid);
		secleft = wdt_priv->wdt_shm->timeleft;
		if(secleft <= 0){
			sem_v(wdt_priv->semid);
			system("echo 0 > ./a.txt");  //do something
			while(1){
				sem_p(wdt_priv->semid);
				secleft = wdt_priv->wdt_shm->timeleft;
				sem_v(wdt_priv->semid);
				if(secleft > 0){
					system("echo 1 > ./a.txt");  //do something
					break;
				}
				sleep(1);
			}
		}else{
			secleft -= 1;
			wdt_priv->wdt_shm->timeleft = secleft;
			sem_v(wdt_priv->semid);
		}
		sleep(1);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒江独钓2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值