简单进程池实现代码(共享内存为通信形式)

本文介绍了一个使用信号量和共享内存实现的进程池模型。该模型通过信号量控制任务的分配与完成,并利用共享内存来共享数据结构,实现进程间通信。文中详细展示了信号量初始化、P/V操作及进程池的初始化、任务添加等关键步骤。

测试效果(代码没有测试完全可能有很多问题后面需要更改

sem.h

#include <stdio.h>
#include <signal.h>
#include <assert.h>
#include <sys/sem.h>
union semun
{
		int val;

};
void sem_init();
void sem_p();
void sem_v();
void del_sem();

sem.c

#include "sem.h"
static int semid=-1;
void sem_init()
{
		semid=semget((key_t)1234,1,IPC_CREAT | IPC_EXCL |0600);//创建信号量
		if(semid==-1)//失败的话就进行获取保证两个进程都能获得同一个信号量
		{
				semid=semget((key_t)1234,1,0600);//获取信号量
				if(semid==-1)
				{
						perror("erro\n");
				}

		}
		else
		{
				union semun a;
				a.val=1;
				if(semctl(semid,0,SETVAL,a)==-1)//添加控制信号量的信息
				{
						perror("semctl erro");
				}
		}
}
void sem_p()
{
		struct sembuf a; //用当前的结构对自己定义的信号进行操作
		a.sem_num=0;
		a.sem_op=-1;
		a.sem_flg=SEM_UNDO;
		if(semop(semid,&a,1)==-1)
		{
				perror("erro\n");
		}
}
void sem_v()
{
		struct sembuf a;
		a.sem_num=0;
		a.sem_op=1;
		a.sem_flg=SEM_UNDO;
		if(semop(semid,&a,1)==-1)
		{
				perror("error\n");
		}

}
void del_sem()
{
		//union semun sem_union;
		if(semctl(semid,0,IPC_RMID)==-1)
		{
				perror("erro\n");
		}
}
sem.c
#include "sem.h"
#include <sys/shm.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int shmid;
typedef void (*process)(void *arg);
typedef struct work1
{
	process dealfun;
	void* arg;
	struct work1 *next;
}CProc_work;
typedef struct
{
		int max_work;
		int num_work;
		int deal_work;
		int deal_max_work;
		int exit;
		int rdc_work;
		CProc_work work[20];

}CProc_pool;
void f(void *arg)
{
		int p=(int)arg;
		printf("%d\n",p);
}
void fun(int i)
{
		pid_t pid;
		int stat;
		while((pid==waitpid(-1,&stat,WNOHANG))>0)
		{
				printf("child_proc exit\n",pid);
		}
}
void init(CProc_pool *pool)
{
	pool->max_work=10;
	pool->num_work=3;
	pool->deal_work=0;
	pool->exit=0;
	pool->rdc_work=0;
	pool->deal_max_work=20;
	int i=0;
	int pid;
	for(;i<pool->num_work;i++)
	{
			pid=fork();
			if(pid==0)
			{
				sem_init();
				CProc_pool *pool=(CProc_pool*)shmat(shmid,NULL,0);
			//	printf("%d\n",pool->deal_work);
				CProc_work work;
				while(1)
				{
						while(pool->deal_work==0);//需要解决方案
						sem_p();
						if(pool->deal_work!=0)
						{
							printf("获取当前的任务 pid=%d\n",getpid());
							pool->deal_work--;
							work=pool->work[pool->deal_work];
							//获取当前的任务;
						}
						else
						{
								sem_v();
								continue;
						}
						printf("runing \n");
						work.dealfun(work.arg);
						sem_v();
						int n=rand()%3;
						sleep(n);
				}
				
				
			}
	}
}
void add(CProc_pool *pool,process p,void *arg)
{
		CProc_work tmp;
		tmp.dealfun=p;
		tmp.arg=arg;
		sem_p();
		pool->work[pool->deal_work]=tmp;
		pool->deal_work++;
		sem_v();
}
int main()
{
		signal(SIGCHLD,fun);
		shmid=shmget((key_t)6666,sizeof(CProc_pool)+1,IPC_CREAT |0600);
		assert(shmid!=-1);
		sem_init();
		CProc_pool *pool=(CProc_pool*)shmat(shmid,NULL,0);
		assert(pool!=(CProc_pool*)-1);
		init(pool);
		CProc_work work;
		int i=0;
		for(;i<10;i++)
		{
			while(pool->deal_work==20);
			add(pool,f,(void*)i);
			sleep(3);
		}
		shmdt(pool);

}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值