Linux 多线程-互斥锁-解析配置-回调函数开发实例

源码目录结构

.
.
├── cfg
│ └── conf.json
├── inc
│ ├── parson.h
│ └── ssh.h
├── Makefile
└── src
├── main.c
├── parson.c
└── ssh.c

源码

main.c

#include <stdio.h>
#include<pthread.h>
#include <signal.h> 
#include <stdlib.h> /*exit*/
#include <unistd.h> /*access*/
#include <string.h>
#include <sys/prctl.h>
#include "parson.h"
#include "ssh.h"

#define LOG_ERR 0
#define LOG_WARN 1
#define LOG_INFO 2
static int debug_level=LOG_INFO;
#define DEBUG(level, fmt, args...) do{ \
        if(level <= debug_level) \
            fprintf(stderr, "%s:%s:%d:"fmt, __FILE__, __FUNCTION__, __LINE__, ##args); \
}while(0)

static int exit_sig = 0;
static int quit_sig = 0;
static void sig_handler(int sigio)
{
	if (sigio == SIGQUIT) {
		quit_sig = 1;;
	} else if ((sigio == SIGINT) || (sigio == SIGTERM)) {
		exit_sig = 1;
	}
}

typedef struct{
/*ssh:0 off ssh:1 on*/
	int ssh;
} act_t;
act_t action;

typedef struct{
	int (*fun)(void);
} fun_t;
fun_t function;

static int count=0;
static pthread_mutex_t mx_count = PTHREAD_MUTEX_INITIALIZER;

void thread_sub(void){
	prctl(PR_SET_NAME, "third_sub");
	while(!exit_sig || !quit_sig){
		DEBUG(LOG_INFO, "this is thread_sub, count=%d\n", count);
		pthread_mutex_lock(&mx_count);
		count--;
		pthread_mutex_unlock(&mx_count);
        DEBUG(LOG_INFO, "this is thread_sub, count=%d\n", count);
        sleep(2);
	}
}
void thread_add(void){
	prctl(PR_SET_NAME, "third_add");
	while(!exit_sig && !quit_sig){
		DEBUG(LOG_INFO, "this is thread_add, count=%d\n", count);
		pthread_mutex_lock(&mx_count);
		count++;
        DEBUG(LOG_INFO, "this is thread_add, count=%d\n", count);
		pthread_mutex_unlock(&mx_count);
        sleep(2);
	}

}

static int parse_conf(const char * conf_file) 
{
    const char conf_obj[] = "action";
	
    char param_name[32]; /* used to generate variable parameter names */
    const char *str; /* used to store string value from JSON object */

    JSON_Value *root_val;
    JSON_Object *root = NULL;
    JSON_Object *conf = NULL;
	JSON_Object *child_conf = NULL;
    //JSON_Value *val;

    /* try to parse JSON */
    root_val = json_parse_file_with_comments(conf_file);
    root = json_value_get_object(root_val);
    if (root == NULL) {
        DEBUG(LOG_ERR, "ERROR: %s is not a valid JSON file\n", conf_file);
        exit(EXIT_FAILURE);
    }
	memset(&action, 0, sizeof(act_t));
    conf = json_object_get_object(root, conf_obj);
    if (conf == NULL) {
        DEBUG(LOG_ERR, "INFO: %s does not contain a JSON object named %s\n", conf_file, conf_obj);
        return -1;
    } else {
        DEBUG(LOG_INFO, "INFO: %s does contain a JSON object named %s\n", conf_file, conf_obj);
		snprintf(param_name, sizeof(param_name), "ssh");
		action.ssh = (int)json_object_dotget_number(conf, param_name);		
        DEBUG(LOG_INFO, "INFO: ssh is %d\n", action.ssh);
		if(action.ssh){
			function.fun=ssh_on;
			DEBUG(LOG_INFO, "INFO: fun.ssh:%p ssh:%p\n", function.fun, ssh_on);
		}
		else
			function.fun=ssh_off;
    }
    json_value_free(root_val);
    return 0;
}


int main(int argc, char *argv[]){
    pthread_t sub_thrid;
    pthread_t add_thrid;
    int thread_ret=-1;
	const char conf_file[]="conf.json";
	prctl(PR_SET_NAME, "fun_main");
    struct sigaction sigact;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = sig_handler;
    sigaction(SIGQUIT, &sigact, NULL); /* Ctrl-\ */
    sigaction(SIGINT, &sigact, NULL); /* Ctrl-C */
    sigaction(SIGTERM, &sigact, NULL); /* default "kill" command */

	if (access(conf_file, R_OK) == 0) {
		DEBUG(LOG_INFO, "INFO: found debug configuration file %s, other configuration files will be ignored\n", conf_file);
		parse_conf(conf_file);
	}else{
        DEBUG(LOG_ERR, "ERROR: failed to find any configuration file named %s\n", conf_file);
        exit(EXIT_FAILURE);
	}
    thread_ret = pthread_create( &sub_thrid, NULL, (void * (*)(void *))thread_sub, NULL);
    if(thread_ret != 0){
        DEBUG(LOG_ERR, "create thread_sub failed\n");
        exit(EXIT_FAILURE);
    }
    thread_ret = pthread_create( &add_thrid, NULL, (void * (*)(void *))thread_add, NULL);
    if(thread_ret != 0){
        DEBUG(LOG_ERR, "create thread_pub failed\n");
        exit(EXIT_FAILURE);
    }
    while(!exit_sig && !quit_sig){
		DEBUG(LOG_INFO, "INFO2: fun:%p \n", function.fun);
			function.fun();
            sleep(2);
    }
    thread_ret = pthread_cancel(sub_thrid);
    if(thread_ret != 0){
        DEBUG(LOG_ERR, "cancel thread_sub failed\n");
        exit(EXIT_FAILURE);
    }
    thread_ret = pthread_cancel(add_thrid);
    if(thread_ret != 0){
        DEBUG(LOG_ERR, "cancel thread_add failed\n");
        exit(EXIT_FAILURE);
    }

    DEBUG(LOG_INFO, "exit fun_main process success\n");
    exit(EXIT_SUCCESS);
}




ssh.c

#include <stdio.h>
#include "ssh.h"
int ssh_on(void){
	printf("this is ssh on func\n");
}
int ssh_off(void){
	printf("this is ssh off func\n");
}

ssh.h

#ifndef _SSH_H_
#define _SSH_H_
extern int ssh_on(void);
extern int ssh_off(void);
#endif

conf.json

{
    "action": {
        "ssh": 0
	}
}

Makefile

SRC=$(wildcard ./src/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))
TAR=./tar/fun
INC=./inc

all:$(TAR)

$(TAR):$(OBJ)
	$(CC) $(CFLAGS) -I$(INC) -o $@ $^ -lpthread 

%.o:%.c
	@if ! [ -d ./tar ];then \
		mkdir -p tar; \
	fi;
	@cp ./cfg/conf.json ./tar/conf.json
	$(CC) $(CFLAGS) -I$(INC) -o $@ -c $<

.PHONY:clean
clean:
	rm -rf ./tar src/*.o 

执行结构

查看线程

cecport@ubuntu:~/training/pthread_parse_callback/tar$ ps -T
  PID  SPID TTY          TIME CMD
 6007  6007 pts/3    00:00:04 bash
28328 28328 pts/3    00:00:00 fun_main
28328 28329 pts/3    00:00:00 third_sub
28328 28330 pts/3    00:00:00 third_add
28332 28332 pts/3    00:00:00 ps

查看执行结果

cecport@ubuntu:~/training/pthread_parse_callback/tar$ ./fun 
src/main.c:main:127:INFO: found debug configuration file conf.json, other configuration files will be ignored
src/main.c:parse_conf:95:INFO: conf.json does contain a JSON object named action
src/main.c:parse_conf:98:INFO: ssh is 0
src/main.c:main:146:INFO2: fun:0x406705 
this is ssh off func
src/main.c:thread_add:59:this is thread_add, count=0
src/main.c:thread_add:62:this is thread_add, count=1
src/main.c:thread_sub:48:this is thread_sub, count=1
src/main.c:thread_sub:52:this is thread_sub, count=0
src/main.c:main:146:INFO2: fun:0x406705 
this is ssh off func
src/main.c:thread_add:59:this is thread_add, count=0
src/main.c:thread_add:62:this is thread_add, count=1
src/main.c:thread_sub:48:this is thread_sub, count=1
src/main.c:thread_sub:52:this is thread_sub, count=0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值