首页 > 系统相关 >简易动态进程池

简易动态进程池

时间:2025-01-07 10:44:07浏览次数:8  
标签:include int void pid pos 简易 进程 动态 procArray

/************proto.h********************/

#ifndef __PROTO_H__
#define __PROTO_H__

#define FORMAT "%ld\n"
#define MINIDLEPROCNUM 5
#define MAXIDLEPROCNUM 10
#define MAXPROCNUM 20

#define SERVERPORT "4096"

#endif

 

/************server.c********************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/mman.h>
#include "proto.h"

#define BUFFSIZE 64
#define IPSIZE 40

enum proc_state
{
IDLE_STATE = 0,
BUSY_STATE,
MAX_STATE
};

struct proc_st
{
int state;
pid_t pid;
};

static int idle_num =0;
static int busy_num =0;
static struct proc_st *procArray;
static int sockfd;

static void proc_work(int pos);
static int add_one_worker(void);
static int del_one_worker(void);
static int find_pos(void);
static void show_workProc(void);

static void usr2_handler(int num)
{
fprintf(stdout,"get signal\n");
}

int main()
{
struct sigaction sa, osa;
sigset_t set, oset;
struct sockaddr_in laddr;
int val =1;
int pos;

sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &sa, &osa);

sa.sa_handler = usr2_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGUSR2, &sa, &osa);

sigemptyset(&set);
sigaddset(&set, SIGUSR2);
if(sigprocmask(SIG_BLOCK, &set, &oset)<0)
{
perror("sigprocmask()");
exit(1);
}

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
{
perror("socket()");
exit(1);
}

if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val , sizeof(val))<0)
{
perror("setsockopt()");
exit(1);
}

laddr.sin_family = AF_INET;
laddr.sin_port = htons(atoi(SERVERPORT));
inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);
if(bind(sockfd, (void *)&laddr, sizeof(laddr))<0)
{
perror("bind()");
exit(1);
}

if(listen(sockfd, 100)<0)
{
perror("listen()");
exit(1);
}

procArray = mmap(NULL, sizeof(struct proc_st)*MAXPROCNUM, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if(procArray == MAP_FAILED)
{
perror("mmap()");
exit(1);
}
for(int i=0; i<MAXPROCNUM; i++)
{
procArray[i].state =-1;
}

for(int i=0;i<MINIDLEPROCNUM;i++)
{
pid_t pid;

pos = find_pos();
if(pos <0)
{
fprintf(stderr, "find pos failed\n");
exit(1);
}

//创建进程
pid = fork();
if(pid<0)
{
perror("fork()");
exit(1);
}
if(pid ==0)
{
proc_work(pos);
}
else
{
procArray[pos].state = IDLE_STATE;
procArray[pos].pid = pid;
idle_num ++;
}
}

while(1)
{
//等待SET集信号
sigsuspend(&oset);

if(idle_num <MINIDLEPROCNUM)
{
add_one_worker();
}
if(idle_num >MAXIDLEPROCNUM)
{
del_one_worker();
}
show_workProc();
}
sigprocmask(SIG_SETMASK, &oset, NULL);
close(sockfd);

exit(0);
}

//while true; do (./client &); sleep 1; done

static int add_one_worker(void)
{
pid_t pid;
int pos;

if((idle_num + busy_num)>= MAXPROCNUM)
return -1;

pos = find_pos();
if(pos <0)
{
fprintf(stderr, "find pos failed\n");
exit(1);
}

//创建进程
pid = fork();
if(pid<0)
{
perror("fork()");
exit(1);
}
if(pid ==0)
{

proc_work(pos);
}
else
{
procArray[pos].state = IDLE_STATE;
procArray[pos].pid = pid;
idle_num ++;
}

return 0;
}

static int del_one_worker(void)
{
int i;

for(i=0;i<MAXPROCNUM;i++)
{
if(procArray[i].state == IDLE_STATE)
{
kill(procArray[i].pid, SIGQUIT);
procArray[i].state = -1;
idle_num --;
return 0;
}
}

return 0;
}

static void show_workProc(void)
{
int idle_cal =0, busy_cal =0;
for(int i=0;i<MAXPROCNUM;i++)
{
if(procArray[i].state == -1)
{
//进程未创建
putchar(' ');
}
else if(procArray[i].state == IDLE_STATE)
{
//进程空闲
putchar('.');
idle_cal ++;
}
else if(procArray[i].state == BUSY_STATE)
{
//进程忙碌
putchar('x');
busy_cal ++;
}
}
putchar('\n');
idle_num =idle_cal;
busy_num =busy_cal;
}

static int find_pos(void)
{
int i;

for(i=0;i<MAXPROCNUM;i++)
{
if(procArray[i].state == -1)
return i;
}

return -1;
}

static void proc_work(int pos)
{
int clientfd;
struct sockaddr_in raddr;
socklen_t lenth =0;
time_t currentTime;
char buff[BUFFSIZE];
char ip[IPSIZE];

while(1)
{
clientfd = accept(sockfd, (void *)&raddr, &lenth);
if(clientfd<0)
{
perror("accept()");
continue;
}

//显示客户端信息
// inet_ntop(AF_INET, raddr.sin_addr, ip, IPSIZE);
// sprintf(stdout,"ip:%s port:%d\n",ip, ntohs(raddr.sin_port));

//切换进程状态
procArray[pos].state = BUSY_STATE;
kill(getppid(), SIGUSR2);

//发送时间戳
currentTime = time(NULL);
snprintf(buff, BUFFSIZE, FORMAT, currentTime);
send(clientfd, buff, BUFFSIZE, 0);
sleep(5);
close(clientfd);

//切换进程状态
procArray[pos].state = IDLE_STATE;
kill(getppid(), SIGUSR2);
}
exit(0);
}

 

/********************client.c********************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include "proto.h"

#define BUFFSIZE 40

int main()
{
struct sockaddr_in raddr;
int val =1;
int sockfd;
char buff[BUFFSIZE] = {0};

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
{
perror("socket()");
exit(1);
}

raddr.sin_family = AF_INET;
raddr.sin_port = htons(atoi(SERVERPORT));
inet_pton(AF_INET,"0.0.0.0",&raddr.sin_addr);

if(connect(sockfd, (void *)&raddr, sizeof(raddr))<0)
{
perror("connect()");
exit(1);
}

recv(sockfd, buff, BUFFSIZE, 0);
fprintf(stdout, "%s", buff);

close(sockfd);

exit(0);
}

标签:include,int,void,pid,pos,简易,进程,动态,procArray
From: https://www.cnblogs.com/linux-learn/p/18657098

相关文章

  • Electron进程间如何通信?
    Electron进程间通信主要涉及到主进程(MainProcess)和渲染器进程(RendererProcess)之间的信息交换。在Electron中,这两种进程之间的通信是通过ipcMain和ipcRenderer模块来实现的。以下是Electron进程间通信的几种主要方式:渲染器进程到主进程的单向通信:使用ipcRenderer.sendAPI从......
  • 04-Linux系统编程之进程
    一、进程的概述1.什么是进程进程:即进行中的程序,可执行文件从开始运行到结束运行这段过程就叫进程。2.程序和进程的区别程序:存储在磁盘上、占磁盘空间、静态的。如:我们编写的C语言代码就是程序,存储在我们电脑磁盘上;进程:运行在系统上、占内存空间,动态的,包括进程的创建......
  • 哪个进程在侦听vxlan的udp socket
    intro作为一个分布式虚拟化系统,网络在k8s中有重要意义。不同node上pod如何基于网络进行通讯是一个需要解决的基本/重要问题。在k8s的NetworkingandNetworkPolicy中提到了常用的网络策略。其中的列表显然是按照字典序(而不是使用频率)排列,其中提到了比较常用的flannel模型,这个......
  • WXML (微信小程序模板) 代码,用于根据 item.key 的值动态添加 CSS 类名,从而实现对特定
    文章目录1、logistics-param-wrap.wxml2、logistics-param-wrap.js3、logistics-param-wrap.wxss1、logistics-param-wrap.wxml<viewclass="logistics-param-wrap"><viewclass="logistics-param-title">物流参数</view><vi......
  • HTML&CSS:咦?卡片的动态渐变背景是如何用 CSS 和伪元素实现的?
    这段代码通过CSS动画和伪元素创建了一个具有动态渐变背景的卡片布局,背景渐变在水平方向上循环移动,营造出一种动态的视觉效果.演示效果HTML&CSS<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=......
  • 算法网关视频分析网关小知识:视频分析系统如何提高对动态变化的识别能力?
    在当今快速发展的智能监控领域,视频分析系统对动态变化的识别能力显得尤为重要。无论是用于安全监控、交通管理还是商业客流分析,准确地捕捉和理解视频中的动态变化都是提升系统性能的关键。为了实现这一目标,我们可以从多个方面对视频分析系统进行优化和改进。以下是一些有效的方法......
  • 05动态加载字节码与CommonsCollections3
    test加载java字节码Java字节码广义的字节码——所有能够恢复成一个类并在JVM虚拟机里加载的字节序列利用URLclassLoader加载远程class文件URLClassLoader是默认加载类AppClassLoader的父类,两者的工作流程类似URLClassLoader可以从远程加载.class文件//注意这里没有pac......
  • InvariantStock:利用不变特征学习掌握动态市场的投资策略优化
    “InvariantStock:LearningInvariantFeaturesforMasteringtheShiftingMarket”论文地址:https://arxiv.org/pdf/2409.00671Github地址:https://github.com/Haiyao-Nero/InvariantStock摘要在投资组合管理领域,准确预测股票收益是至关重要的,但传统方法通常未能有......
  • FinDKG: 用于检测金融市场全球趋势的动态知识图谱与大型语言模型
    “FinDKG:DynamicKnowledgeGraphswithLargeLanguageModelsforDetectingGlobalTrendsinFinancialMarkets”论文地址:https://arxiv.org/pdf/2407.10909摘要动态知识图(DKG)能够表示对象间随时间变化的关系,适用于从复杂且非结构化的数据中抽取信息。在金融领......
  • 项目50:简易健康问卷调查【源代码】 --- 《跟着小王学Python·新手》
    项目50:简易健康问卷调查【源代码】—《跟着小王学Python·新手》《跟着小王学Python》是一套精心设计的Python学习教程,适合各个层次的学习者。本教程从基础语法入手,逐步深入到高级应用,以实例驱动的方式,帮助学习者逐步掌握Python的核心概念。通过开发游戏、构建Web应用......