编写函数 process_create(pid_t* pid, void* func, void* arg)

博客主要讲述在Linux环境下,使用C语言封装fork/wait等操作,编写process_create函数。该函数接收pid指针、回调函数func和参数arg,func作为子进程执行的入口函数,arg为其传递参数。

封装fork/wait等操作, 编写函数 process_create(pid_t* pid, void* func, void* arg), func回调函数就是子进程执行的入口函数, arg是传递给func回调函数的参数.

  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <unistd.h>
  7 #include <sys/wait.h>
  8 
  9 //函数指针
 10 typedef void (*FUNC)();
 11 
 12 void *func(void* arg)
 13 {
 14     char* str = (char*)arg;
 15     printf("%s\n", str);
 16     printf("child pid = %d\n", getpid());
 17 }
 18 
 19 //创建进程
 20 int process_create(pid_t* pid, void* func, char* arg)
 21 {
 22     *pid = fork();
 23     if(*pid < 0){
 24         perror("fork error\n");
 25         return -1;
 26     }
 27     else if(*pid == 0){
 28         while(1){
 29             //定义一个函数指针类型,指向那个函数
 30             FUNC funct = (FUNC)func;
 31             //传参传arg,不要传*arg,不然参数不匹配调不到回调函数
 32             funct(arg);
 33             sleep(1);
 34         }
 35     }
 36     else{
 37         pid_t ret = waitpid(-1, NULL, 0);
 38         printf("wait process success\n");
 39     }
 40 }
 41 
 42 int main()
 43 {
 44     char* arg = "child is running!";
 45     pid_t pid;
 46     process_create(&pid, func, arg);
 47     return 0;
 48 }
 49 
 50 
                                          
详细解释函数各部分语句含义: int imi_execute(unsigned long env, IMI_TYPE type, int process, const char* ptr_func_name , IMI_ARGS_STC *ptr_args) { int rv = 0; int sequence = 0; void *ptr_pkt_buf = NULL; int pkt_length = 0; int totLen = 0; TPMSG_MSG imi_tpmsg = {0}; IMI_MSG_HEADER msg_header = {0}; long obuff_info_exist = 0; if( (NULL == ptr_args) || ( NULL == ptr_func_name) || (IMI_MAX_FUN_NAME_SIZE <= strlen(ptr_func_name))) { return -1; } rv = imi_get_conn_sequence(env, &sequence); if (0 != rv) { IMI_DEBUG_PRINTF(IMI_DEBUG_ERROR, "you may forget to call imi_add_conn_env"); goto exec_done; } IMI_DEBUG_PRINTF(IMI_DEBUG_DEBUG, "%s lproc:%d, dproc:%d", __func__, l_imi_local_process, process); if (l_imi_local_process == process) /* local procedure call from the same process */ { IMI_FUN_REGISTER_STC imi_fun_register; IMI_PRINT_ENV print_env = {0}; rv = imi_register_hash_find(ptr_func_name, &imi_fun_register); if (0 != rv) { goto exec_done; } IMI_DEBUG_PRINTF(IMI_DEBUG_DEBUG, "local call func=%s", imi_fun_register.function_name); print_env.sequence = sequence; print_env.process = process; print_env.type = type; pal_tls_key_set(imi_pthr_key, &print_env); /* caoliao: tag机制还不可用,不同线程会获得相同的tag (23Mar16) */ // pal_get_new_tag(); rv = (*imi_fun_register.ptr_func)(&print_env, ptr_args); // pal_free_all_tag(); pal_tls_key_set(imi_pthr_key, NULL); goto exec_done; } /* IMI_MSG_PACKET, args_num*IMI_TLV_ARGS_STC, args_buf, (jumbo str/obuff data) */ totLen = sizeof(IMI_MSG_PACKET); totLen += ptr_args->args_num*sizeof(IMI_TLV_ARGS_STC); totLen += ptr_args->available_index; totLen += ptr_args->extraBufLen; ptr_pkt_buf = (void *)IMI_ALLOC(totLen); if( NULL == ptr_pkt_buf ) { return -1; } msg_header.type = type; memcpy(msg_header.function_name, ptr_func_name, strlen(ptr_func_name)); /* parasoft-suppress PB-34 "wuyongqing" */ /* set the flags of the message */ IMI_MSG_SET_TYPE(msg_header, IMI_MSG_RPC); /* IMI_MSG_SET_OUTPUT_TYPE(msg_header, output_type);*/ IMI_DEBUG_PRINTF(IMI_DEBUG_DEBUG,"sequence=%d", sequence); msg_header.sequence = sequence; rv = imi_packet_build((IMI_MSG_PACKET *)ptr_pkt_buf, &pkt_length, &msg_header, ptr_args); /* parasoft-suppress MISRA2004-16_6 "wuyongqing" */ if( 0 != rv ) { goto exec_done; } IMI_DEBUG_PRINTF(IMI_DEBUG_DEBUG,"pkt_length=%d", pkt_length); /*send the msg */ imi_tpmsg.data = (char *)ptr_pkt_buf; imi_tpmsg.dst_proc = process; IMI_DEBUG_PRINTF(IMI_DEBUG_DEBUG,"dproc1=%d, dproc2=%d", imi_tpmsg.dst_proc, process); imi_tpmsg.len = pkt_length; imi_tpmsg.msg_type = TPMSG_TYPE_IMI; rv = tpmsg_send(&imi_tpmsg); if (0 != rv) { rv = -1; IMI_DEBUG_PRINTF(IMI_DEBUG_ERROR,"tpmsg_send failed"); goto exec_done; } pal_sem_take(IMI_CONNECTION_SEM(sequence),pal_sem_FOREVER); /* parasoft-suppress MISRA-004_a "wuyongqing" */ rv = IMI_CONNECTION_RET_STATUS(sequence); /* parasoft-suppress MISRA-004_a "wuyongqing" */ if (0==imi_param_get_int(ptr_args, "obuff_info_e", &obuff_info_exist) && (-1 != rv)) { pal_sem_take(IMI_CONNECTION_DATA_SEM(sequence),pal_sem_FOREVER); /* parasoft-suppress MISRA-004_a "wuyongqing" */ } exec_done: if (ptr_pkt_buf) { IMI_FREE(ptr_pkt_buf); ptr_pkt_buf = NULL; } return rv; }
最新发布
10-10
/******************************************************************************/ /* */ /* Copyright (c) 2018 TP-Link Systems Inc. */ /* */ /* File : devmgr_main.c */ /* */ /* Description : doing init process of dev-manager */ /* */ /* Author : libin */ /* */ /******************************************************************************/ /* INCLUDE HEADER FILE */ #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #include <libubox/uloop.h> #include <libubus-ext.h> #include <uci_blobmsg.h> #include "devmgr_global.h" #include "devmgr_sock.h" #include "devmgr_dev_ctrl.h" #include "devmgr_dev_list.h" #ifdef CFG_DEVMGR_MASTER #include "devmgr_ubus_master.h" #include "devmgr_devctl_master.h" #else #include <sys/mman.h> #include <errno.h> #include "devmgr_ubus_slaver.h" #include "devmgr_devctl_slaver.h" #include "devmgr_config_slaver.h" #endif /* MACRO DEFINITION */ #define DM_PID_FILE "/var/run/devmgr.pid" #define DM_FILE_OPEN_FLAG (O_RDWR | O_CREAT) #define DM_FILE_OPEN_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /******************************************************************************* Function : file_write_lock Description : lock a file with write lock from the beginning of the file Input : fd @ the file descriptor Output : N/A Return : 0 @ success -1 @ failed *******************************************************************************/ static int file_write_lock(int fd) { struct flock lock; memset(&lock, 0, sizeof(lock)); lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; if (fcntl(fd, F_SETLK, &lock) < 0) { return -1; } return 0; } /******************************************************************************* Function : pid_file_create Description : create pid file to prevent a second program start to run Input : N/A Output : N/A Return : 0 @ success -1 @ failed *******************************************************************************/ static int pid_file_create() { int fd; char buf[16] = {}; fd = open(DM_PID_FILE, DM_FILE_OPEN_FLAG, DM_FILE_OPEN_MODE); if (fd < 0) { DBG_NOTICE("open %s failed: %s\n", DM_PID_FILE, strerror(errno)); return -1; } if (file_write_lock(fd) < 0) { if (EACCES == errno || EAGAIN == errno) { DBG_NOTICE("process are already running\n"); close(fd); return -1; } DBG_NOTICE("cannot lock %s: %s\n", DM_PID_FILE, strerror(errno)); close(fd); return -1; } ftruncate(fd, 0); snprintf(buf, sizeof(buf), "%d", getpid()); write(fd, buf, strlen(buf) + 1); return 0; } /******************************************************************************* Function : devmgr_ubus_init Description : init ubus interface Input : void Output : N/A Return : void *******************************************************************************/ void devmgr_ubus_init() { #ifdef CFG_DEVMGR_MASTER master_ubus_init(); #else slaver_ubus_init(); #endif } /******************************************************************************* Function : devmgr_devctl_init Description : init device control interface Input : void Output : N/A Return : void *******************************************************************************/ void devmgr_devctl_init() { #ifdef CFG_DEVMGR_MASTER master_devctl_init(); #else slaver_devctl_init(); #endif } /******************************************************************************* Function : devmgr_config_init Description : read config and init some global variables Input : void Output : N/A Return : void *******************************************************************************/ void devmgr_config_init() { device_list_init(); #ifdef CFG_DEVMGR_MASTER devmgr_migrate_init(); device_list_update_timer_init(); device_list_upgrade_dev_timer_init(); device_heartbeart_freq_init(); #else slaver_hub_ipaddr_init(); slaver_onboarding_step_init(); slaver_start(); #endif } #ifdef CFG_DEVMGR_SLAVER #if defined(DEV_C420) || defined(DEV_C400) || defined(DEV_D230) || defined(DEV_D200) static int calculate_mem_size() { int s = 0, m = 0, c = 0; char buf[1024] = {0}, *tmp = NULL; FILE * fp = fopen("/proc/cmdline", "r"); if (fp) { fread(buf, sizeof(buf), 1, fp); fclose(fp); if ((tmp = strstr(buf, "mem=")) != NULL && sscanf(tmp + sizeof("mem=") - 1, "%d", &m) == 1) { s += m; } if ((tmp = strstr(buf, "rmem=")) != NULL && sscanf(tmp + sizeof("rmem=") - 1, "%d", &m) == 1) { s += m; } } return s; } //x^16 + x^12 + x^5 + x^0 #define CRC16_POLY_LE 0x8408 void devmgr_crc_calculation(uint8_t *crc_code, uint8_t *dat, uint8_t len){ uint8_t i; uint16_t crc = 0; crc = ~crc; while (len--) { crc ^= *dat++; for (i = 0; i < 8; i++) { crc = (crc >> 1) ^ ((crc & 1) ? CRC16_POLY_LE : 0); } } crc = ~crc; crc_code[0] = crc>>8; crc_code[1] = (crc & 0x00FF); } static uint8_t devmgr_check_read_mcu(unsigned char *fb_data, int base){ unsigned char data[20]; unsigned char crc_code[2]; unsigned char crc_code_calc[2]; #ifdef DOORBELL_FUNCTION_SUPPORT uint8_t len = 9, i; for(i=0; i<len; i++){ data[i] = *((unsigned char *)(fb_data + base + i)); } crc_code[0] = *((unsigned char *)(fb_data + base + 0x09)); crc_code[1] = *((unsigned char *)(fb_data + base + 0x0A)); /* DBG_NOTICE("devmgr read boot arg: 0x%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", data[0],data[1],data[2],\ data[3],data[4],data[5],data[6],data[7],data[8],crc_code[0],crc_code[1]); */ #else uint8_t len = 8, i; for(i=0; i<len; i++){ data[i] = *((unsigned char *)(fb_data + base + i)); } crc_code[0] = *((unsigned char *)(fb_data + base + 0x08)); crc_code[1] = *((unsigned char *)(fb_data + base + 0x09)); /* DBG_NOTICE("devmgr read boot arg: 0x%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", data[0],data[1],data[2],\ data[3],data[4],data[5],data[6],data[7],crc_code[0],crc_code[1]); */ #endif devmgr_crc_calculation(crc_code_calc, data, len); //DBG_NOTICE("devmgr crc_code_calc: 0x%02X %02X\n", crc_code_calc[0],crc_code_calc[1]); if(crc_code_calc[0]==crc_code[0] && crc_code_calc[1]==crc_code[1]){ return 1; } return 0; } void devmgr_read_fb_mcu() { static const int memsize = 0x10000; unsigned char *fb_data = NULL; unsigned char event_id = 0; int fd = -1, base = 0xFE00; char buf[512] = {0}; uint8_t ret = 0; if (calculate_mem_size() == 64) { fd = open("/dev/mcu_info", O_RDWR); if (fd < 0) { DBG_ERR("%s:open /dev/mcu_info failed\n", __func__); return; } ioctl(fd, 0, buf); fb_data = buf; base = 0; } else { fd = open("/dev/mem", O_RDWR); if (fd < 0) { DBG_ERR("%s:open /dev/mem failed\n", __func__); return; } fb_data = mmap(0, memsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x37F0000); if ((void*)fb_data == MAP_FAILED) { DBG_ERR("mmap failed with %d %d %d %d %d %d\n", errno, EBADF, EACCES, EINVAL, EAGAIN, ENOMEM); close(fd); return; } } event_id = (fb_data + base)[0]; #ifdef DOORBELL_FUNCTION_SUPPORT ret = devmgr_check_read_mcu(fb_data, base); if(!ret){ DBG_ERR("[devmgr] boot args crc check error, set event_id to 170\n"); slaver_send_task_invalid_event_id(event_id); event_id = 170; } #endif if (event_id == 9) { DBG_NOTICE("recv event id 9 when power on, start to send unbind request to hub\n"); slaver_send_task_unbind(); } else if (event_id == 12) { DM_PRINT("event_id: 12, rejoin req.\n"); slaver_send_task_sub1g_rejoin(); } else if (event_id == 4) { int onboarding_step = slaver_onboarding_step_get(); if (onboarding_step == ONBOARDING_STEP_TOKEN_GET || onboarding_step == ONBOARDING_STEP_SUCCESS) { slaver_heartbeat_send(); } } if (fb_data != buf) munmap(fb_data, memsize); close(fd); } #endif #endif /******************************************************************************* Function : devmgr_init Description : dev-manager initiation Input : void Output : N/A Return : void *******************************************************************************/ void devmgr_init() { #ifdef CFG_DEVMGR_SLAVER #ifdef DEV_KC300 int hibernate_fd = common_hibernate_register("dev-manager"); if (hibernate_fd < 0) { DBG_WARN("hibernate_sync register failed: #%d %s\n", -hibernate_fd, strerror(-hibernate_fd)); } #endif #endif devmgr_ubus_init(); #ifdef CFG_DEVMGR_MASTER master_online_status_init(); #endif devmgr_devctl_init(); devmgr_socket_init(); #ifdef CFG_DEVMGR_SLAVER #ifdef DEV_KC300 if (hibernate_fd >= 0) { common_hibernate_wait_and_close(hibernate_fd); } #endif #endif devmgr_config_init(); #ifdef CFG_DEVMGR_SLAVER #if defined(DEV_C420) || defined(DEV_C400) || defined(DEV_D230) || defined(DEV_D200) devmgr_read_fb_mcu(); #endif #endif } /******************************************************************************* Function : main Description : main function Input : argc @ argv @ Output : N/A Return : 0 *******************************************************************************/ int main(int argc, char *argv[]) { tpdbg_set_module_name("dev-manager"); DBG_NOTICE("dev-manager start\n"); if (pid_file_create() < 0) { exit(1); } uloop_init(); devmgr_init(); uloop_run(); uloop_done(); #ifdef CFG_DEVMGR_MASTER devmgr_battery_statistic_stop(); #endif DBG_NOTICE("dev-manager exit\n"); return 0; }
09-18
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值