最近写了一个多进程的程序。
创建N个进程,主进程查看哪个进程空闲,如果空闲,则把任务通过管道的方式把任务分发给这个进程来完成。
只是简单测试程序。所以还有以下地方需要补充:
1. 父进程对每个子进程没有添加 等待终止的信号。
2. 没有添加ctrl+c的信号控制。
3. 内存有些没有释放,另外函数入口处参数没有检测。
4. 管道都没有关闭,释放什么的。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <dirent.h>
#include <sys/file.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <errno.h>
#define PROCESS_BUSY 1
#define PROCESS_NOT_BUSY 0
/* Process managementstructure */
typedef struct _ProcessList{
int iIndex;
int iPid;
int iStatus;
}ProcessList;
//max 10 process
#define MAX_PROCESS_NUMBER 10
ProcessList *pProcessList = NULL;
sem_t *SemShareMemory;
char acShareFileName[1024] = {0};
int iProcessNumber = MAX_PROCESS_NUMBER;
ProcessList *pstSharedMemory = NULL;
#define SHARE_MEMORY_SEM "sharememory"
int pfd[MAX_PROCESS_NUMBER][2];
/******************************************
* FunctionName:pCreatSem
* Description:create the sem
* Input:the posix name of the sem
* Return:OK, pointer of sem
* Fail, NULL
*******************************************/
sem_t * pCreatSem(const char *pSemName)
{
sem_t *semTmp;
char acTmpErr[1024] = {0};
semTmp = sem_open(pSemName, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1);
if (-1 == semTmp)
{
if (errno == EEXIST)
{
printf("%s already here /n",pSemName);
if (-1 == sem_unlink(pSemName))
{
printf(" unlink sem %s error/n",pSemName);
return NULL;
}
}
else
{
printf(" Open sem %s error /n",pSemName);
return NULL;
}
semTmp = sem_open(pSemName, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1);
if (-1 == semTmp)
{
printf(" Second create sem create error/n");
return NULL;
}
}
if (-1 == sem_unlink(pSemName))
{
printf(" unlink sem %s error /n",pSemName);
return NULL;
}
return semTmp;
}
/*init processlist */
int iInitShareProcessList( int MaxProcessNum)
{
int iFd = 0;
int i;
ProcessList *pstProcessRecord = NULL;
/* P-sem operate */
if (-1 == sem_wait(SemShareMemory))
{
return -1;
}
iFd = open(acShareFileName,O_RDWR | O_CREAT,S_IRWXU);
if(iFd == -1)
{
return -1;
}
pstProcessRecord = (ProcessList *)malloc(sizeof(ProcessList) * MaxProcessNum);
if(pstProcessRecord == NULL)
{
return -1;
}
memset(pstProcessRecord,0,sizeof(ProcessList) * MaxProcessNum);
for(i = 0;i<MaxProcessNum; i++)
{
(pstProcessRecord+i)->iPid = -1;
(pstProcessRecord+i)->iIndex = i;
(pstProcessRecord+i)->iStatus = PROCESS_NOT_BUSY;
}
write(iFd,pstProcessRecord,(sizeof(ProcessList)*MaxProcessNum));
free(pstProcessRecord);
pstSharedMemory = (ProcessList *)mmap(NULL,sizeof(ProcessList) * MaxProcessNum,
PROT_READ | PROT_WRITE,MAP_SHARED,iFd,0);
if(pstSharedMemory == (void *)(-1))
{
return -1;
}
/* V-sem operate */
if (-1==sem_post(SemShareMemory))
{
printf("sem_wait error/n");
return -1;
}
return 0;
}
int iSetPid(int iIndex,int iPid)
{
/***P-sem operate***/
if (-1==sem_wait(SemShareMemory))
{
return -1;
}
(*(pstSharedMemory+iIndex)).iPid = iPid;
/***V-sem operate***/
if (-1==sem_post(SemShareMemory))
{
return -1;
}
return 0;
}
int iSetProcessBusy(int iIndex)
{
/***P-sem operate***/
if (-1==sem_wait(SemShareMemory))
{
return -1;
}
(*(pstSharedMemory+iIndex)).iStatus = PROCESS_BUSY;
/***V-sem operate***/
if (-1==sem_post(SemShareMemory))
{
return -1;
}
return 0;
}
int iSetProcessNotBusy(int iIndex)
{
/***P-sem operate***/
if (-1==sem_wait(SemShareMemory))
{
return -1;
}
(*(pstSharedMemory+iIndex)).iStatus = PROCESS_NOT_BUSY;
/***V-sem operate***/
if (-1==sem_post(SemShareMemory))
{
return -1;
}
return 0;
}
int iGetIndex(int *piIndex,int iPid)
{
int i = 0;
/***P-sem operate***/
if (-1==sem_wait(SemShareMemory))
{
return -1;
}
*piIndex = -1;
for(i=0; i< iProcessNumber;i++)
{
if((*(pstSharedMemory+i)).iPid == iPid)
{
*piIndex = i;
break;
}
}
/***V-sem operate***/
if (-1==sem_post(SemShareMemory))
{
return -1;
}
return 0;
}
int iGetNotBusyProcess(int *piIndex)
{
int i = 0;
/***P-sem operate***/
if (-1==sem_wait(SemShareMemory))
{
return -1;
}
*piIndex = -1;
for(i=0; i< iProcessNumber;i++)
{
if((*(pstSharedMemory+i)).iStatus ==PROCESS_NOT_BUSY)
{
*piIndex = i;
break;
}
}
/***V-sem operate***/
if (-1==sem_post(SemShareMemory))
{
return -1;
}
return 0;
}
int iProcessTask(int iIndex)
{
int iPid = 0;
char acName[1024] = {0 };
int n = 0;
int iRet = 0;
printf(" child %d is in /n",iIndex );
//init oci
while(1)
{
n=read(pfd[iIndex][0],acName,1024);
printf("children %d n = %d read %s /n",iIndex,n,acName);
// process the tack
sleep(1);
/* set not busy */
iSetProcessNotBusy(iIndex);
}
// close oci
return 0;
}
int iCreateProcess()
{
int i;
int iRet = 0;
int iPid = 0;
for(i=0; i<iProcessNumber; i++)
{
iRet=pipe(pfd[i]);
if(iRet<0)
{
printf("pipe create err!!!!!/n");
}
iPid = fork();
switch(iPid)
{
case -1:
printf("create process error /n");
break;
case 0:
/*this is child ,go to process the request;*/
printf("come to child /n");
close(pfd[i][1]);
iRet = iProcessTask(i);
if(iRet != 0)
{
printf("process client request return error :iRet = %d/n",iRet);
}
close(pfd[i][0]);
exit(0);
break;
default: /* parent process*/
close(pfd[i][0]);
iRet = iSetPid(i,iPid);
continue;
break;
}
}
}
void main()
{
int iRet = 0;
char acName[] = "test.sh";
int iPid = 0;
int iIndex = 0;
char acBuffer[1024] = {0};
int iNumber = 0;
strcpy(acShareFileName,acName);
/*建立共享有名信号量*/
SemShareMemory = pCreatSem(SHARE_MEMORY_SEM);
/*init share memory */
iRet = iInitShareProcessList(iProcessNumber);
/* create process */
iRet = iCreateProcess();
/* send task to process */
while(1)
{
iRet = iGetNotBusyProcess(&iIndex);
//all busy ,must wait
if(iIndex == -1 )
{
continue;
}
iSetProcessBusy(iIndex);
iNumber++;
sprintf(acBuffer,"%s%d","tP",iNumber);
write(pfd[iIndex][1],acBuffer,sizeof(acBuffer));
}
}