各位大虾,有事麻烦大家帮忙查查,关于多进程并发服务器信号量同步问题,在此先谢过了!!(真心只有20分,望大家给予帮助,谢谢))
各位大虾,有事麻烦大家帮忙查查,关于多进程并发服务器信号量同步问题,在此先谢过了!!
最近在编写多进程并发服务器时,运用同步与互斥信号量相关操作遇到一些问题,先上代码和截图,方便讨论:
//
//进程池服务器demo
//
#include "std.h"
#include <iostream>
#define LISTENQUEUE 10
#define MAXDATA 1024
#define PORT 5678
#define COUNT 2
#define SHAREMAX 10
#define max(a,b) ((a) > (b) ? (a) : (b))
using namespace std;
//服务器子进程与进程池处理进程共享内存结构
struct shared{
sem_t wmutex, rmutex; //读写同步信号量
char result[SHAREMAX]; //处理进程处理结果
int fd; //客户请求fd
}share;
//服务器与服务器子进程共享内存结构
struct requestQueue{
int requestFd[SHAREMAX]; //缓冲数组,服务器传递客户请求fd给子进程
int total_count;//共享内存总请求数
int current_count;//共享内存当前处理请求数
sem_t mutex; //互斥信号量
}requestQ;
void initProcessPool( struct shared * ptr , struct requestQueue *reqPtr);
int main( int argc, char *argv[] )
{
size_t serverSocketfd, clientSocketfd, numberOfChar;
struct sockaddr_in serverAddr, clientAddr;
socklen_t addrLen = sizeof(struct sockaddr_in);
char buf[] = "lxj";
fd_set readFSet;
struct timeval delayTime;
int maxFd = 0, selectCode = 0;
int i, fd, ncount = 0;
struct shared *ptr;
struct requestQueue *reqPtr;
//init share memory
fd = Open( argv[1], O_RDWR | O_CREAT, 6 );
Write( fd, &share, sizeof(struct shared) );
ptr = (struct shared *)Mmap( NULL, sizeof(struct shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
reqPtr = (struct requestQueue *)Mmap( NULL, sizeof(struct requestQueue), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
Sem_init(&ptr->rmutex, 1, 0);
Sem_init(&ptr->wmutex, 1, 1);
Sem_init(&reqPtr->mutex, 1, 1);
reqPtr->total_count = reqPtr->current_count = 0;
close(fd);
initProcessPool( iProcessCount, ptr, reqPtr);
//socket
serverSocketfd = Socket( AF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind
Bind( serverSocketfd, (struct sockaddr *) & serverAddr, sizeof(serverAddr) );
//listen
Listen( serverSocketfd, LISTENQUEUE );
//signal off
signal( SIGCHLD, SIG_IGN );
FD_ZERO( &readFSet );
delayTime.tv_sec = 0;
delayTime.tv_usec = 0;
//suspend for waiting client to connect
while(1)
{
//printf("waiting client...");
FD_SET( serverSocketfd, &readFSet );
maxFd = max(serverSocketfd, maxFd) + 1;
selectCode = Select( maxFd, &readFSet, NULL, NULL, &delayTime);
//client connect server
if( FD_ISSET(serverSocketfd, &readFSet) )
{
clientSocketfd = Accept( serverSocketfd, (struct sockaddr *)&serverAddr, &addrLen );
{
Sem_wait( &reqPtr->mutex );
//服务器获取服务器与服务器子进程共享内存互斥锁,若数组不满则放入请求
//否则打印退出
if( (reqPtr->total_count + 1)% SHAREMAX != reqPtr->current_count % SHAREMAX )
{
reqPtr->requestFd[reqPtr->total_count++ % SHAREMAX] = clientSocketfd ;
}
else
{
cout << "queue full" << endl;
exit(1);
}
Sem_post( &reqPtr->mutex );
}
//阻塞在进程池可读的同步信号量,若进程池处理完,会释放
{
Sem_wait( &ptr->rmutex );
printf("server: result %s\t \n", ptr->result);
Sem_post( &ptr->wmutex );
}
Send(clientSocketfd, buf, sizeof(buf), 0);
close(clientSocketfd);
}
}
}
void initProcessPool( struct shared * ptr , struct requestQueue *reqPtr)
{
pid_t pid;
pid = Fork();
if( pid == 0 )
{
//进程池
while(1)
{
//若服务器与服务器子进程共享内存放入的请求已经处理完或未放入请求,则等待新的请求
Sem_wait( &reqPtr->mutex );
if( reqPtr->total_count == reqPtr->current_count )
{
Sem_post( &reqPtr->mutex );
continue;
}
//新的请求进来则向服务器子进程与进程池的共享内存中写入数据,post服务器可读同步信号量
Sem_wait( &ptr->wmutex );
memcpy(&ptr->result, "lxj", 3);
ptr->fd = reqPtr->requestFd[reqPtr->current_count++ % SHAREMAX];
cout << "current_count: " << reqPtr->current_count << endl;
cout << "total_count: " << reqPtr->total_count << endl;
Sem_post( &ptr->rmutex );
Sem_post( &reqPtr->mutex );
}
exit(1);
}
}
运行截图如下:
current_count: 1
total_count: 2
current_count: 2
total_count: 2
server: result lxj
current_count: 3
total_count: 1
current_count: 4
total_count: 1
current_count: 5
total_count: 1
current_count: 6
total_count: 1
预想结果:
current_count: 1
total_count: 1
我客户端只发了一次请求,不知道为什么打了这么多次,查了多次同步于互斥信号量,未发现问题(可能没查到核心),烦请各位大虾出手相助,万分感谢,在线等。。。 服务器
[解决办法]
信号量能不能跨进程?
[解决办法]
多进程的sem要用sem_open,sem_init只能单一进程的多线程同步。
man sem_overview