?? c_shm.cpp
字號:
/***********************************************************************
* Module: c_shm.cpp
* Author: Administrator
* Modified: 2005年9月15日 9:18:09
* Purpose: Implementation of the class c_shm
* Comment: 共享內存基本類. 一個共享內存由多個內存塊組成。獲得共享內存時, 就可以獲得多個共享內存塊對象。 通過, 這么多個塊對象對塊中的數據進行操作。
***********************************************************************/
#include "c_shm_mem.h"
#include "c_shm.h"
////////////////////////////////////////////////////////////////////////
// Name: c_shm::c_shm()
// Purpose: 構造函數
// Return:
// Comment: 初始化c_info_info對象
////////////////////////////////////////////////////////////////////////
c_shm::c_shm()
{
para.loadPara();
p_share_info = new c_share_info();
share_area_id = 0;
//取得共享內存內需要加載的所有內存塊信息,放入到vector中。
loadShmInfo();
v_share_area_name.clear();
}
////////////////////////////////////////////////////////////////////////
// Name: c_shm::c_shm(int t_share_area_id)
// Purpose: 構造函數
// Parameters:
// - t_share_area_id: 共享內存區ID
// Return:
// Comment: 初始化c_info_info對象
////////////////////////////////////////////////////////////////////////
c_shm::c_shm( int t_share_area_id )
{
para.loadPara();
p_share_info = new c_share_info();
share_area_id = t_share_area_id;
//取得共享內存內需要加載的所有內存塊信息,放入到vector中。
loadShmInfo();
v_share_area_name.clear();
}
////////////////////////////////////////////////////////////////////////
// Name: c_shm::c_shm(const char* t_share_area_name)
// Purpose: 構造函數
// Parameters:
// - t_share_area_name: 共享內存區名字
// Return:
// Comment: 初始化c_info_info對象
////////////////////////////////////////////////////////////////////////
c_shm::c_shm( const char* t_share_area_name )
{
para.loadPara();
p_share_info = new c_share_info();
if ( strcmp(t_share_area_name,"")== 0 )
share_area_id = 0;
else
{
share_area_id = p_share_info->getShareID(t_share_area_name);
if( share_area_id == -1 )
exit(1);
}
//取得共享內存內需要加載的所有內存塊信息,放入到vector中。
loadShmInfo();
}
////////////////////////////////////////////////////////////////////////
// Name: c_shm::~c_shm()
// Purpose: 析構函數
// Return:
// Comment: 刪除c_shm_mem對象與c_share_info對象
////////////////////////////////////////////////////////////////////////
c_shm::~c_shm()
{
for( int i = 0; i < v_shm_mem.size() ; i ++ )
{
if( v_shm_mem[i]->p_share_mem_info->application_kind == '0' )
{
delete v_shm_mem[i];
}
else if( v_shm_mem[i]->p_share_mem_info->application_kind == '1' )
{
c_shm_merge* p_temp = (c_shm_merge*)(v_shm_mem[i]);
delete p_temp;
}
else
{
delete v_shm_mem[i];
}
}
delete p_share_info;
}
////////////////////////////////////////////////////////////////////////
// Name: c_shm::createshm()
// Purpose: 創建共享內存
// Return: int 成功:0 失敗:其它
// Comment: 計算共享內存區的大小,并創建。把各共享內存塊的信息寫入內存區中,并劃好大小。
////////////////////////////////////////////////////////////////////////
int c_shm::createshm(void)
{
// TODO : implement
int oflag = SHM_R|SHM_W|IPC_CREAT;
//取得共享內存的大小
size_t shmSize = getMemSize();
//創建共享內存
key_t shm_key;
shm_key = ftok( para.getChar( "shm", "path_name"), share_area_id );
shmId = shmget( shm_key, shmSize, oflag);
theLog<<"共享內存Key:"<<shm_key<<",總大小"<shmSize<endi;
c_shm_merge* p_shm_merge;
if( shmId == -1)
{
cout<<"創建共享內存錯誤"<<endl;
/*cout<<"創建共享內存錯誤"<<errno<<endl;
if( errno == EINVAL )
cout<<"EINVAL"<<endl;
else if( errno == EACCES )
cout<<"EACCES"<<endl;
else if( errno == ENOENT )
cout<<"ENOENT"<<endl;
else if( errno == ENOMEM )
cout<<"ENOMEM"<<endl;
else if( errno == ENOSPC )
cout<<"ENOSPC"<<endl;
else if( errno == EEXIST )
cout<<"標識已存在"<<endl;
*/
exit(1); //ENOENT
}
//往共享內存內放共享內存塊的信息,并用head指針vector確定位置
shm_area_head = (char*)shmat( shmId, NULL, 0 );
int i, j;
int point = 0;
c_mutex p_mutex;
int block_count;
c_shm_mem_load_data* p_shm_mem_load;
c_shm_merge* p_shm_mem_merge;
c_shm_mem* p_shm_mem;
//確定每個結構體的大小,不足16位的加夠16位
int size_share_mem_info = sizeof(SHARE_MEM_INFO);
int add_size_share_mem_info;
if( size_share_mem_info % 16 == 0 )
{
add_size_share_mem_info = size_share_mem_info;
}
else
{
add_size_share_mem_info = ( size_share_mem_info / 16 + 1 ) * 16 ;
}
int size_stshareinfo = sizeof( STSHAREINFO );
int add_size_stshareinfo;
if( size_stshareinfo % 16 == 0 )
{
add_size_stshareinfo = size_stshareinfo;
}
else
{
add_size_stshareinfo = ( size_stshareinfo / 16 + 1 ) * 16 ;
}
for( i = 0; i < v_share_mem_info.size(); i++)
{
switch(v_share_mem_info[i].application_kind)
{
case '0':
p_shm_mem_load = new c_shm_mem_load_data();
p_shm_mem_load->p_share_mem_info = (SHARE_MEM_INFO*)&(shm_area_head[ point ]);
memcpy( p_shm_mem_load->p_share_mem_info, &(v_share_mem_info[i]), size_share_mem_info );
v_shm_head.push_back ( p_shm_mem_load->p_share_mem_info );
point += add_size_share_mem_info;
//設置頭信息
p_shm_mem_load->p_stShareInfo = (STSHAREINFO*)&((( char * )shm_area_head)[ point ]);
point += add_size_stshareinfo;
p_shm_mem_load->p_field_info = (MEM_FIELD*)&(shm_area_head[ point ]);
point += 4000;
p_shm_mem_load->p_stShareInfo->mem_area_no = v_share_mem_info[i].mem_area_no;
p_shm_mem_load->p_stShareInfo->real_record_count = 0;
p_shm_mem_load->p_stShareInfo->append_record_count = 0;
p_shm_mem_load->head_point = (char*)&(shm_area_head[ point ]);
//設置可用標志
p_shm_mem_load->p_stShareInfo->valid_flag = 1;
//加鎖
p_mutex._mutex = &(p_shm_mem_load->p_stShareInfo->append_lock);
p_mutex.init();
//;
block_count = p_shm_mem_load->p_share_mem_info->mem_size / p_shm_mem_load->p_share_mem_info->block_size + 1 ;
if( block_count > UPDATE_LOCK_COUNT )
block_count = UPDATE_LOCK_COUNT;
for( j = 0 ; j < block_count ; j ++ )
{
p_mutex._mutex = &(p_shm_mem_load->p_stShareInfo->update_lock[j]);
p_mutex.init();
}
p_shm_mem_load->p_stShareInfo->block_count = block_count;
p_shm_mem_load->p_share_mem_info->block_size = p_shm_mem_load->p_share_mem_info->mem_size/block_count+1;
p_mutex._mutex = &(p_shm_mem_load->p_stShareInfo->record_count_lock);
p_mutex.init();
p_mutex._mutex = &(p_shm_mem_load->p_stShareInfo->append_key_lock);
p_mutex.init();
//////2005-11-23
p_shm_mem_load->p_stShareInfo->addition_pos = 0;
p_shm_mem_load->addition_point = &(p_shm_mem_load->head_point[p_shm_mem_load->p_share_mem_info->mem_size-p_shm_mem_load->p_share_mem_info->addition_size]);
p_mutex._mutex = &(p_shm_mem_load->p_stShareInfo->addition_lock);
p_mutex.init();
delete p_shm_mem_load;
break;
case '1':
p_shm_mem_merge = new c_shm_merge();
p_shm_mem_merge->p_share_mem_info = (SHARE_MEM_INFO*)&(shm_area_head[ point ]);
memcpy( p_shm_mem_merge->p_share_mem_info, &(v_share_mem_info[i]), sizeof(SHARE_MEM_INFO) );
v_shm_head.push_back ( p_shm_mem_merge->p_share_mem_info );
point += add_size_share_mem_info;
//設置頭信息
p_shm_mem_merge->p_stShareInfo = (STSHAREINFO*)&((( char * )shm_area_head)[ point ]);
point += add_size_stshareinfo;
p_shm_mem_merge->p_field_info = (MEM_FIELD*)&(shm_area_head[ point ]);
point += 4000;
p_shm_mem_merge->p_stShareInfo->mem_area_no = v_share_mem_info[i].mem_area_no;
p_shm_mem_merge->p_stShareInfo->real_record_count = 0;
p_shm_mem_merge->p_stShareInfo->append_record_count = 0;
p_shm_mem_merge->head_point = (char*)&(shm_area_head[ point ]);
//設置可用標志
p_shm_mem_merge->p_stShareInfo->valid_flag = 1;
//加鎖
p_mutex._mutex = &(p_shm_mem_merge->p_stShareInfo->append_lock);
p_mutex.init();
//;
block_count = p_shm_mem_merge->p_share_mem_info->mem_size / p_shm_mem_merge->p_share_mem_info->block_size + 1 ;
if( block_count > UPDATE_LOCK_COUNT )
block_count = UPDATE_LOCK_COUNT;
for( j = 0 ; j < MAX_ITEM_COUNT ; j ++ )
{
p_mutex._mutex = &(p_shm_mem_merge->p_stShareInfo->update_lock[j]);
p_mutex.init();
}
p_shm_mem_merge->p_stShareInfo->block_count = block_count;
p_shm_mem_merge->p_share_mem_info->block_size = p_shm_mem_merge->p_share_mem_info->mem_size/block_count+1;
p_mutex._mutex = &(p_shm_mem_merge->p_stShareInfo->record_count_lock);
p_mutex.init();
p_mutex._mutex = &(p_shm_mem_merge->p_stShareInfo->append_key_lock);
p_mutex.init();
p_shm_mem_merge->createItemShm();
//調整塊大小
p_shm_mem_merge->p_share_mem_info->block_size = (p_shm_mem_merge->p_share_mem_info->mem_size - SHM_ITEM_SIZE*MAX_ITEM_COUNT)/block_count+1;
strcpy(p_shm_mem_merge->backup_dir , para.getChar( "shm", "ShmBackupDir"));
p_shm_mem_merge->max_backup_num = para.getInt( "shm", "MaxBackupNum" );
delete p_shm_mem_merge;
break;
default:
p_shm_mem = new c_shm_mem();
p_shm_mem->p_share_mem_info = (SHARE_MEM_INFO*)&(shm_area_head[ point ]);
memcpy( p_shm_mem->p_share_mem_info, &(v_share_mem_info[i]), sizeof(SHARE_MEM_INFO) );
v_shm_head.push_back ( p_shm_mem->p_share_mem_info );
point += add_size_share_mem_info;
//設置頭信息
p_shm_mem->p_stShareInfo = (STSHAREINFO*)&((( char * )shm_area_head)[ point ]);
point += add_size_stshareinfo;
p_shm_mem->p_field_info = (MEM_FIELD*)&(shm_area_head[ point ]);
point += 4000;
p_shm_mem->p_stShareInfo->mem_area_no = v_share_mem_info[i].mem_area_no;
p_shm_mem->p_stShareInfo->real_record_count = 0;
p_shm_mem->p_stShareInfo->append_record_count = 0;
p_shm_mem->head_point = (char*)&(shm_area_head[ point ]);
//設置可用標志
p_shm_mem->p_stShareInfo->valid_flag = 1;
//加鎖
p_mutex._mutex = &(p_shm_mem->p_stShareInfo->append_lock);
p_mutex.init();
//;
block_count = p_shm_mem->p_share_mem_info->mem_size / p_shm_mem->p_share_mem_info->block_size + 1 ;
if( block_count > UPDATE_LOCK_COUNT )
block_count = UPDATE_LOCK_COUNT;
for( j = 0 ; j < block_count ; j ++ )
{
p_mutex._mutex = &(p_shm_mem->p_stShareInfo->update_lock[j]);
p_mutex.init();
}
p_shm_mem->p_stShareInfo->block_count = block_count;
p_shm_mem->p_share_mem_info->block_size = p_shm_mem->p_share_mem_info->mem_size/block_count+1;
p_mutex._mutex = &(p_shm_mem->p_stShareInfo->record_count_lock);
p_mutex.init();
p_mutex._mutex = &(p_shm_mem->p_stShareInfo->append_key_lock);
p_mutex.init();
break;
}
if( v_share_mem_info[i].mem_size % 16 == 0 )
{
point += v_share_mem_info[i].mem_size;
}
else
{
point += (v_share_mem_info[i].mem_size / 16 + 1 ) * 16;
}
}
shmctl( shmId, IPC_STAT, &shmBuf);
return 0;
}
////////////////////////////////////////////////////////////////////////
// Name: c_shm::getshm()
// Purpose: 取得共享內存區,并加載各共享內存塊的信息到c_shm_mem的vector中。
// Return: int
////////////////////////////////////////////////////////////////////////
int c_shm::getshm(void)
{
// TODO : implement
int oflag = SHM_R|SHM_W;
//取得共享內存的大小
size_t shmSize = getMemSize();
//獲取共享內存
key_t shm_key;
shm_key = ftok( para.getChar( "shm", "path_name"), share_area_id );
shmId = shmget( shm_key, shmSize, oflag);
//獲取失敗
if( shmId == -1)
{
theLog<<"獲取共享內存"<<shm_key<<"|"<<share_area_id<<"|"<<para.getChar( "shm", "path_name")<<"失敗"<<ende;
exit(1);
}
shm_area_head = (char*)shmat(shmId, NULL, 0);
//從共享內存中讀取配置信息,并生成c_shm_mem的vector
//SHARE_MEM_INFO* t_share_mem_info = (SHARE_MEM_INFO*)&(shm_area_head[0]);
//cout<<"read mem size:"<<t_share_mem_info->mem_size<<endl;
//v_shm_mem.clear();
char* p = para.getChar( "shm", "stor_path_na" );
char* pp = para.getChar( "shm", "ShmBackupDir") ;
int dfe = para.getInt( "shm", "MaxBackupNum" );
int point = 0;
int i = 0;
int add_count = 0;
SHARE_MEM_INFO* t_share_mem_info;// = (SHARE_MEM_INFO*)&shm_area_head[point];
int size_mem_field = sizeof( MEM_FIELD );
c_mutex p_mutex;
//確定每個結構體的大小,不足16位的加夠16位
int size_share_mem_info = sizeof(SHARE_MEM_INFO);
int add_size_share_mem_info;
if( size_share_mem_info % 16 == 0 )
{
add_size_share_mem_info = size_share_mem_info;
}
else
{
add_size_share_mem_info = ( size_share_mem_info / 16 + 1 ) * 16 ;
}
int size_stshareinfo = sizeof( STSHAREINFO );
int add_size_stshareinfo;
if( size_stshareinfo % 16 == 0 )
{
add_size_stshareinfo = size_stshareinfo;
}
else
{
add_size_stshareinfo = ( size_stshareinfo / 16 + 1 ) * 16 ;
}
while( ((point+add_count*4*16) < shmSize) && ( (t_share_mem_info = (SHARE_MEM_INFO*)&(shm_area_head[point])) != NULL) )
{
add_count ++;
point += add_size_share_mem_info;
STSHAREINFO* t_stshareinfo = (STSHAREINFO*)&(shm_area_head[ point ]);
point += add_size_stshareinfo;
MEM_FIELD* memField = (MEM_FIELD*)&(shm_area_head[ point ]);
point += 4000;
//test
//vector <c_shm_mem *> v_shm_mem1;
c_shm_mem_load_data* t_shm_load_data;
c_shm_mem* t_shm_mem;
c_shm_merge* t_shm_merge;
switch( t_share_mem_info->application_kind )
{
case '0':
//資料類,修改時,先刪除原有記錄,再添加一條新記錄
t_shm_load_data = new c_shm_mem_load_data();
t_shm_load_data->p_share_mem_info = t_share_mem_info;
t_shm_load_data->p_stShareInfo = t_stshareinfo;
t_shm_load_data->p_field_info = memField;
t_shm_load_data->head_point = &shm_area_head[ point];;
//生成鎖
t_shm_load_data->append_mutex._mutex = &(t_stshareinfo->append_lock);
t_shm_load_data->record_count_mutex._mutex = &(t_shm_load_data->p_stShareInfo->record_count_lock);
t_shm_load_data->v_update_mutex.clear();
for( i = 0 ; i < t_shm_load_data->p_stShareInfo->block_count ; i ++ )
{
c_mutex t_mutex;
t_mutex._mutex = &(t_shm_load_data->p_stShareInfo->update_lock[i]);
t_shm_load_data->v_update_mutex.push_back( t_mutex );
}
t_shm_load_data->append_key_mutex._mutex = &(t_shm_load_data->p_stShareInfo->append_key_lock);
//拷貝路徑
strcpy( t_shm_load_data->file_path, p );
////////////////2005-11-23
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -