Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >设计模式(4)-序列生成器之单例模式

设计模式(4)-序列生成器之单例模式

作者头像
cloudskyme
发布于 2018-03-20 08:55:28
发布于 2018-03-20 08:55:28
91300
代码可运行
举报
文章被收录于专栏:cloudskymecloudskyme
运行总次数:0
代码可运行

场景:序列生成器

系统中统一的序列生成程序,整个系统统一一套!那么就用单例模式吧!

首先看看单例模式

1)类持有一个自己的实例,而且还是个静态实例。

2)类的构造函数为私有属性。

3)用以获得实例的方法为静态方法。

看看类图

然后看一段试例程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

using namespace std;

class Singleton{
private:   
	Singleton();//注意:构造方法私有   
	virtual ~Singleton();   
	static Singleton* instance;//惟一实例   
	int var;//成员变量(用于测试)   
public:   
	static Singleton* GetInstance();//工厂方法(用来获得实例)   
	int getVar();//获得var的值   
	void setVar(int);//设置var的值 
};
//构造方法实现 
Singleton::Singleton()   
{   
	this->var = 20;   
	cout<<"Singleton Constructor"<<endl;   
} 
Singleton::~Singleton()
{
	if(instance != NULL)
	{
		delete instance;
	}
}
//初始化静态成员   
//Singleton* Singleton::instance=new Singleton();  
Singleton* Singleton::instance=NULL;
Singleton* Singleton::GetInstance()   
{   
	if(instance == NULL)
	{
		instance = new Singleton();
	}
	return instance;   
}   
//seter && getter含数   
int Singleton::getVar()   
{   
	return this->var;   
}   
void Singleton::setVar(int var)   
{   
	this->var = var;   
}   

int main(int argc, char* argv[])
{
	Singleton *ton1 = Singleton::GetInstance();
	Singleton *ton2 = Singleton::GetInstance();
	cout<<"ton1 var = "<<ton1->getVar()<<endl;   
	ton1->setVar(150);  
	cout<<"ton2 var = "<<ton2->getVar()<<endl;
	return 0;
}

1、构造方法私有

那么,就意味着,只能在Singleton的成员函数中,才能调用Singleton的构造函数来创建实例。在Singleton之外,不能创建Singleton对象的实例。

2、代码中,定义了GetInstance方法,只能通过GetInstance方法来获取Singleton对象的实例,单例就是在GetInstance方法中控制的。

首先,Singleton有一个 static Singleton* instance;//惟一实例 

Singleton* Singleton::instance=NULL; 在这里初始化为NULL。

Singleton* Singleton::GetInstance()   {    if(instance == NULL)  {   instance = new Singleton();  }  return instance;   }  

上面的函数,就是通过instance来实现单例的。

当第一次调用GetInstance时,instance 为NULL,所以会执行 instance = new Singleton(); 把这个新建的实例保存到静态成员instance,并返回这个指针。

第二次到第N次调用GetInstance时,由于instance不为空,所以会直接返回instance 。也就是第一次调用GetInstance创建的那个实例。

所以这样就实现了,单实例。

意思就是说,Singleton对象的实例,只会被创建一次,就是说内存中,只存在一个Singleton的实例,就是所谓,单实例。

弄个生成单例的实例程序吧!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <sys/sem.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <iostream>  

using namespace std;  


#define MAXID	9999
static struct sembuf op_open={1,-1,0  };

class GenHH{
	private:
		GenHH();//注意:构造方法私有 
    	virtual ~GenHH();    
    	static GenHH* instance;//惟一实例
		int opensem(key_t semkey);
		int creatsem(key_t semkey,int bigcount);
		int sem_open(int semid);
		unsigned int gen_seq();
	public:
		static GenHH* getInstance();//工厂方法(用来获得实例) 
		unsigned int gen_hh();
}

GenHH::~GenHH()
{
	if(instance != NULL)  
    {  
        delete instance;  
    }
}

//初始化静态成员
GenHH* GenHH::instance=NULL;
GenHH* GenHH::getInstance()
{
	if(instance == NULL)  
    {  
        instance = new Singleton();  
    }  
    return instance; 
}

unsigned int GenHH::gen_hh()
{
	unsigned int hh;
	char	chh[9];

	memset(chh,0,9);

	sprintf(chh,"%05d%04d",time(NULL)%100000,gen_seq());

	hh = atoi(chh);

	return hh;
}

unsigned int GenHH::gen_seq()
{
	int	seq,kid;
	int	semid,semval;

	struct timeval  tv;


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

	kid=ftok("/etc/hosts",'m');
	if(kid<0){
		printf("system Error! Can't find  /etc/hosts!\n");
		gettimeofday(&tv, NULL);
		return tv.tv_usec % MAXID ;
	}

	semid=opensem(kid);
	if(semid<=0){
		semid=creatsem(kid,MAXID);
		if(semid<0){
			gettimeofday(&tv, NULL);
			return tv.tv_usec % MAXID ;
		}
	}

	semval=semctl(semid,1,GETVAL,0);
	if(semval<=2){
		semctl_arg.val=MAXID;
                if ((semctl(semid,1,SETVAL,semctl_arg)) < 0 ){
			gettimeofday(&tv, NULL);
			return tv.tv_usec % MAXID ;
		}
	}
	
	sem_open(semid);
	semval=semctl(semid,1,GETVAL,0);


	return MAXID-semval;
}

int GenHH::opensem(key_t semkey)
{
	int semid;

    semid=semget(semkey,2,0);
    if(semid<0){
            printf("semaphoreid get error!\n");
            return -1;
    }

     return semid;
}

int GenHH::creatsem(key_t semkey,int bigcount)
{
	int semid,semval;
	union semun {
		int val;
		struct semid_ds *buf;
                unsigned short *array;
	} semctl_arg;

	semid=semget(semkey,2,IPC_CREAT|0600);
	if(semid<0){
		return -1;
	}

	if((semval=semctl(semid,1,GETVAL,0))<0)
		printf("GETVAL error!\n");
	else if(semval==0){
		semctl_arg.val=1;
		if(semctl(semid,0,SETVAL,semctl_arg)<0)
			printf("SETVAL error\n");

		semctl_arg.val=bigcount;
		if(( semctl(semid,1,SETVAL,semctl_arg)) < 0 )
			printf("setval error\n");
	}

	return semid;
}

int GenHH::sem_open(int semid)
{
	while(( semop(semid,&op_open,1) ) < 0 ){
		if( errno==EINTR ) {
			usleep(5000);
			continue;
		}
		printf("sem op_open error!\n");
		return -1;
	}
	return 0;
}

int main(int argc, char* argv[])  
{
	GenHH *genHH1 = GenHH::getInstance();
	GenHH *genHH2 = GenHH::getInstance();

	cout<<genHH1->gen_hh()<<endl;
	cout<<genHH2->gen_hh()<<endl;
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2011-04-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
设计模式之单例模式
单例模式,顾名思义就是只有一个实例,并且她自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象
Java宝典
2021/07/15
4710
设计模式-单例模式
学习了单例模式,自己记一下笔记,本文从一个单例模式开始进行一步一步的演进,使用c#语言,在实现上会结合C#的特性。演进过程为 单线程无参数单例模式->多线程无参数单例模式->.net特性多线程无参数单例模式->单线程有参数单例模式->多线程有参数单例模式->.net特性多线程有参数单例模式
MaybeHC
2024/04/23
1360
设计模式-单例模式
java设计模式(四)--单例模式
 Singleton最熟悉不过了,下面学习单例模式。转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处: 1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。 3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系
Ryan-Miao
2018/03/13
7930
设计模式之单例模式
  Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。   单例模式能够保证一个类仅有唯一的实例,并提供一个全局访问点。单例模式主要有3个特点:
雨落凋殇
2019/12/25
4290
【设计模式】各个击破单例模式的8种写法
在一个系统开发过程中,我们在基于节省内存资源、保证数据内容的一致性的考虑上,往往需要对某些类要求只能创建一个实例,即「保证类只有一个实例」的设计模式就是单例模式。
行百里er
2020/12/16
3040
【设计模式】各个击破单例模式的8种写法
Linux信号量及函数
信号量,或称信号灯,其原理是一种数据操作锁的概念,本身不具备数据交换的功能,它负责协调各个进程,保证保证两个或多个关键代码段不被并发调用,确保公共资源的合理使用。信号量分为单值和多值两种。
xxpcb
2020/08/04
2.2K0
linux网络编程之System V 信号量(一):封装一个信号量集操作函数的工具
信号量的概念参见这里。 与消息队列和共享内存一样,信号量集也有自己的数据结构: struct semid_ds { struct ipc_perm sem_perm;  /* Ownership a
s1mba
2017/12/28
1.8K0
Linux进程间通信(中)之信号、信号量实践
我们使用过windows的都知道,当一个程序被卡死的时候不管怎样都没反应,这样我们就可以打开任务管理器直接强制性的结束这个进程,这个方法的实现就是和Linux上通过生成信号和捕获信号来实现相似的,运行过程中进程捕获到这些信号做出相应的操作使最终被终止。
杨源鑫
2020/09/14
5.7K0
Linux进程间通信(五) - 信号灯(史上最全)及其经典应用案例
信号灯概述 什么是信号灯 信号灯用来实现同步,用于多线程,多进程之间同步共享资源(临界资源)。 PV原语:信号灯使用PV原语 P原语操作的动作是: u sem减1。 u sem减1后仍大于或等于零,则进程继续执行。 u 若sem减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。 V原语操作的动作是: u sem加1。 u 若相加结果大于零,则进程继续执行。 u 若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。 信号灯分类 按信号灯实
三丰SanFeng
2018/01/16
2K0
Linux进程间通信(五) - 信号灯(史上最全)及其经典应用案例
Linux 的进程间通信:信号量
本文介绍了Linux信号量、POSIX信号量、Linux条件变量和Linux线程同步基本概念,并通过代码示例展示了如何使用这些技术进行线程同步。
邹立巍
2017/07/25
6.9K0
linux进程间通信方式最常用_linux进程调度
管道可用于具有亲缘关系进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
全栈程序员站长
2022/11/10
2.2K0
信号量--System V信号量 与 Posix信号量
信号量是一种计数器,用来控制对多个进程/线程共享的资源进行访问。常和锁一同使用。 在某个进程/线程正在对某个资源进行访问时,信号量可以阻止另一个进程/线程去打扰。 生产者和消费者模型是信号量的典型使用。
看、未来
2020/08/26
1.7K0
【设计模式】之单例模式
单例模式属于管理实例的创造型类型模式。单例模式保证在你的应用种最多只有一个指定类的实例。
青山师
2023/05/05
2880
javascript设计模式一: 单例模式
作为一个半路出家的前端,随着项目经验的积累,也越来越意识到原生js的博大精深,最近正在研究js设计模式,接下来每学一个设计模式就是写篇文章做笔记,其实主要还是代码和设计思想的结合,努力体会,多思考合适自己项目中的应用场景,争取实际应用到实际项目中。
前端_AWhile
2019/08/29
4980
设计模式之单例模式
单例模式是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点以获取该实例。它是一种创建型模式,通常用于需要严格控制某个类的实例数量的情况。单例模式确保一个类在整个应用程序生命周期中只有一个实例,因此可以节省系统资源,同时提供了一个集中的访问点,以便在需要时获取该实例。
孟斯特
2023/09/23
3050
设计模式之单例模式
设计模式之单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。单例模式广泛应用于Android开发中,例如管理全局状态、缓存、日志记录、数据库连接等。
用户11397231
2024/12/18
1400
[设计模式]单例模式
静默虚空
2018/01/05
1.6K0
[设计模式]单例模式
设计模式-单例模式
模式定义 确保一个类最多只有一个实例,并提供一个全局访问点。 单例模式分为饿汉式和懒汉式。 懒汉式单例模式:在类加载时不初始化。 饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。 饿汉式-线程安全 1 /** 2 * 饿汉式单例模式(线程安全) 3 */ 4 public class Singleton { 5 //static单例变量 6 private static Singleton singleton = new Singleton()
武培轩
2018/04/18
5620
【JavaScript设计模式】-- 单例模式
某些JavaScript的UI组件中,需要获取页面的DOM对象,只需要调用getInstance方法时返回该实例(调用时才判断是否已被初始化)的引用即可。
meteoric
2018/11/15
3700
c 线程安全的单例模式-设计模式之单例模式(C++版)
  单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。
宜轩
2022/12/29
9070
相关推荐
设计模式之单例模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验