修改生产者和消费者都退出后,共享内存未删除的问题

生产者消费者注册信号处理函数,退出时检查如果没有其它进程使用共享内存,将共享内存删除
This commit is contained in:
guo_peixu
2022-06-30 15:16:08 +08:00
parent 89899d2d0a
commit 8267c9712e
6 changed files with 102 additions and 21 deletions

View File

@@ -164,8 +164,8 @@ int main(int argc, char ** args)
{
pthread_create(&t[i], NULL, thread_logger, (void *)(unsigned long)(i));
}
signal(SIGINT, sig_int_handler);
signal(SIGHUP, sig_hup_handler);
//signal(SIGINT, sig_int_handler);
//signal(SIGHUP, sig_hup_handler);
while(1)
;
//MESA_destroy_runtime_log_handle(sample_handle);

View File

@@ -37,16 +37,17 @@ struct MESA_shm_queue_head{
};
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_status);
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, int **consumer_status);
struct MESA_shm_queue_head *MESA_shm_get_ring_queue();
void MESA_shm_init_mutex();
void MESA_shm_init_overview();
void MESA_shm_init();
void MESA_shm_recycle_ring_queue(struct MESA_shm_queue_head *ring_queue_head);
int MESA_shm_copy_buf_to_ring_queue(char *buf, int buflen, struct MESA_shm_queue_head *head, char *log_file, int log_file_len);
int MESA_shm_ring_queue_is_empty(struct MESA_shm_queue_head *head);
int MESA_shm_ring_queue_is_full(struct MESA_shm_queue_head *head);
void MESA_shm_ring_queue_set_empty(struct MESA_shm_queue_head *head);
int MESA_shm_get_consumer_status();
void MESA_shm_unlink(struct MESA_shm_overview *ovw, int ovw_shmid);
#endif

View File

@@ -24,7 +24,6 @@
#define CONSUMER_CARE_PID_SPEC 1
#define CONSUMER_CARE_PID_MAX_LEN 128
int g_cur_tty_fd = -1;
struct log_file_list{
char log_file_pre[MESA_SHM_LOG_PATH_LEN];
@@ -44,6 +43,10 @@ struct care_pid_list g_care_pid_list;
int g_output_mode = CONSUMER_OUTPUT_MODE_FILE;
int g_care_pid = CONSUMER_CARE_PID_ALL;
int *g_status = NULL;
int g_cur_tty_fd = -1;
struct MESA_shm_overview *g_shm_overview = NULL;
int g_shm_overview_id = -1;
void init_ring_queue_head_arrray(struct MESA_shm_overview *ovw, struct MESA_shm_queue_head **ring_queue_head)
{
@@ -514,12 +517,33 @@ error:
}
void signal_handler_exit(int signum)
{
if(g_status == NULL){
exit(0);
struct shmid_ds buf;
if(g_status != NULL){
*g_status = MESA_CONSUMER_NOT_RUNNING;
}
*g_status = MESA_CONSUMER_NOT_RUNNING;
if(g_shm_overview == NULL || g_shm_overview_id == -1){
goto out;
}
if(shmctl(g_shm_overview_id, IPC_STAT, &buf) == -1){
goto out;
}
if(buf.shm_nattch <= 1){
/*
This is the last process to use this shared memory,
we need to unlink the shared memory before the process exit
*/
MESA_shm_unlink(g_shm_overview, g_shm_overview_id);
}
out:
exit(0);
}
/*
if we use shmctl function and IPC_RMID parameter,
the shared memory will actually be destroyed only after the last process detaches it,
but no more attaches for the shared memory identified by the shmid parameter are allowed,
producer process and consumer process start at an indeterminate time,
so we have to use IPC_RMID parameter to unlink the shared memory when all processes exit
*/
void register_sginal_handler()
{
signal(SIGKILL, signal_handler_exit);
@@ -564,20 +588,20 @@ int main(int argc, char **argv)
}
int i = 0;
int ret = 0;
struct MESA_shm_overview *shm_overview = NULL;
struct MESA_shm_overview *tmp_ovw = NULL;
struct MESA_shm_queue_head *ring_queue_head[MESA_SHM_RING_QUEUE_NUM] = {NULL};
INIT_LIST_HEAD(&g_log_file_list.list);
ret = MESA_shm_alloc_overview(&shm_overview, &g_status);
ret = MESA_shm_alloc_overview(&g_shm_overview, &g_shm_overview_id, &g_status);
if(ret < 0){
return 0;
}
*g_status = MESA_CONSUMER_RUNNING;
register_sginal_handler();
init_ring_queue_head_arrray(shm_overview, ring_queue_head);
init_ring_queue_head_arrray(g_shm_overview, ring_queue_head);
while(1){
for(i = 0; i< MESA_SHM_RING_QUEUE_NUM; i++){
tmp_ovw = shm_overview + i;
tmp_ovw = g_shm_overview + i;
if(tmp_ovw->shmid == -1){
break;
}

View File

@@ -264,7 +264,7 @@ void MESA_free_pthread_private(void *arg)
void MESA_alloc_pthread_key()
{
pthread_key_create(&MESA_pthread_key, MESA_free_pthread_private);
MESA_shm_init_overview();
MESA_shm_init();
return ;
}

View File

@@ -7,14 +7,15 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include "MESA_handle_logger.h"
#include "MESA_shm_ring_queue.h"
#include "list.h"
struct MESA_shm_overview *MESA_shm_ovw = NULL;
int *MESA_consumer_status = NULL;
struct MESA_shm_queue_head *MESA_ring_queue_head[MESA_SHM_RING_QUEUE_NUM] = {NULL};
int MESA_shm_ovw_id = -1;
void MESA_shm_init_ring_queue_mutex(struct MESA_shm_overview *ovw)
@@ -34,8 +35,61 @@ int MESA_shm_get_consumer_status()
}
return *MESA_consumer_status;
}
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_status)
void MESA_shm_unlink(struct MESA_shm_overview *ovw, int ovw_shmid)
{
int i;
struct MESA_shm_overview *tmp_ovw;
if(ovw == NULL || ovw_shmid == -1){
return ;
}
for(i = 0; i < MESA_SHM_RING_QUEUE_NUM; i++){
tmp_ovw = ovw + i;
if(tmp_ovw->shmid != -1){
shmctl(tmp_ovw->shmid, IPC_RMID, NULL);
}
}
shmctl(ovw_shmid, IPC_RMID, NULL);
return ;
}
void MESA_shm_check_unlink(int signum)
{
struct shmid_ds buf;
if(MESA_shm_ovw == NULL || MESA_shm_ovw_id == -1){
return ;
}
if(shmctl(MESA_shm_ovw_id, IPC_STAT, &buf) == -1){
return ;
}
if(buf.shm_nattch <= 1){
/*
This is the last process to use this shared memory,
we need to unlink the shared memory before the process exit
*/
MESA_shm_unlink(MESA_shm_ovw, MESA_shm_ovw_id);
}
exit(0);
}
/*
if we use shmctl function and IPC_RMID parameter,
the shared memory will actually be destroyed only after the last process detaches it,
but no more attaches for the shared memory identified by the shmid parameter are allowed,
producer process and consumer process start at an indeterminate time,
so we have to use IPC_RMID parameter to unlink the shared memory when all processes exit
*/
void MESA_shm_register_sginal_handler()
{
signal(SIGKILL, MESA_shm_check_unlink);
signal(SIGTRAP, MESA_shm_check_unlink);
signal(SIGABRT, MESA_shm_check_unlink);
signal(SIGBUS, MESA_shm_check_unlink);
signal(SIGFPE, MESA_shm_check_unlink);
signal(SIGSEGV, MESA_shm_check_unlink);
signal(SIGTERM, MESA_shm_check_unlink);
signal(SIGINT, MESA_shm_check_unlink);
signal(SIGQUIT, MESA_shm_check_unlink);
return ;
}
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, int **consumer_status)
{
int shmsize = (sizeof(struct MESA_shm_overview) * MESA_SHM_RING_QUEUE_NUM) + sizeof(int);
struct MESA_shm_overview *shm_overview = NULL;
@@ -61,6 +115,7 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_statu
}
*ovw = shm_overview;
*consumer_status = (int *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
*ovw_id = shmid;
}
}else{
shm_overview = (struct MESA_shm_overview *)shmat(shmid, NULL, 0);
@@ -69,14 +124,16 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_statu
}
*ovw = shm_overview;
*consumer_status = (int *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
*ovw_id = shmid;
}
return 0;
}
void MESA_shm_init_overview()
void MESA_shm_init()
{
if(MESA_shm_ovw == NULL || MESA_consumer_status == NULL){
MESA_shm_alloc_overview(&MESA_shm_ovw, &MESA_consumer_status);
if(MESA_shm_ovw == NULL || MESA_consumer_status == NULL || MESA_shm_ovw_id == -1){
MESA_shm_alloc_overview(&MESA_shm_ovw, &MESA_shm_ovw_id, &MESA_consumer_status);
}
MESA_shm_register_sginal_handler();
return ;
}
@@ -89,7 +146,6 @@ void MESA_shm_init_new_ring_queue(struct MESA_shm_queue_head *head, struct MESA_
head->ovw_idx = ovw->idx;
return ;
}
void MESA_shm_recycle_ring_queue(struct MESA_shm_queue_head *ring_queue_head)
{
if(MESA_shm_ovw == NULL){

View File

@@ -1,4 +1,4 @@
{
global: MESA*runtime_log*;GIT_VERSION_*;MESA_shm_alloc*;MESA_handle_fmt_rule_register;MESA_shm_ring_queue*;
global: MESA*runtime_log*;GIT_VERSION_*;MESA_shm_alloc*;MESA_handle_fmt_rule_register;MESA_shm_ring_queue*;MESA_shm_unlink;
local: *;
};