信号灯控制并发进程问题?急
来源: 互联网 发布时间:2016-05-28
本文导语: while( 1 ){ fprintf( stderr, "STARTn"); if( itcp_poll( ) == -1 ){ //tcp监听阻塞函数,负责接收客户端的链接请求, sleep( 5 ); continue ; } memset( &semops, 0, sizeof( struct sembuf ) ); semops....
while( 1 ){
fprintf( stderr, "STARTn");
if( itcp_poll( ) == -1 ){ //tcp监听阻塞函数,负责接收客户端的链接请求,
sleep( 5 );
continue ;
}
memset( &semops, 0, sizeof( struct sembuf ) );
semops.sem_num = 0 ;
semops.sem_op = 1 ;
semops.sem_flg = SEM_UNDO ;
semop( semid2, ( struct sembuf * )&semops, 1 ) ;
rc = semctl( semid2, 0, GETVAL, 0 );
fprintf( stderr, "rc=[%d]ADDn", rc);
if (rc>30 //预期想通过同一时段并发的进程不超过30(使用信号灯跟踪)
{
fprintf( stderr, "rc>30n");
itcp_clear( );
continue; //不产生子进程,直接退出
}
switch( fork( ) ){
case 0 :
fprintf( stderr, "CHILDREN DEALn");
doClient( ); //子进程处理函数,处理具体交易,通讯时间可能较长
fprintf( stderr, "doClient OVERn");
itcp_clear( );
memset( &semops, 0, sizeof( struct sembuf ) );
semops.sem_num = 0 ;
semops.sem_op = -1 ;
semops.sem_flg = SEM_UNDO ;
semop( semid2, ( struct sembuf * ) &semops, 1 ) ;
rc = semctl( semid2, 0, GETVAL, 0 );
fprintf( stderr, "rc=[%d]DELETEn", rc);
exit(0);
default:
fprintf( stderr, "default DEALn");
itcp_clear( );
break;
}
}
上述server程序,本意想通过信号灯控制并发进程数不超过30,即doClient未退出的时候信号灯数量继续+1,退出的话信号灯-1,实际跟踪发现每次执行顺序都是
rc=[1]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[0]DELETE
rc=[2]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[1]DELETE
rc=[3]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[2]DELETE
问题就是不论doClient处理函数是否返回,"ADD"对应的信号灯值不会因为"DELETE"的处理完成而同步,不知道是否因为父子进程完全继承的原因,子进程继承了上一主继承的所有特性,子进程的修改不会映射到父进程?是否因为父子进程权限修改原因?而且上述处理在doclient一直堵塞的情况未退出的情况下今后也会堆积累加到30,还是不符合我需求的只判断某一时段同时并发进程树不超过30的需求,烦请大家指点,谢谢大家了。同事细听是否semop的参数也会导致,"ADD"与"DELETE"处理不能同步处理同一semid,时间紧迫,有知道的兄弟们帮忙了,再次感谢!
fprintf( stderr, "STARTn");
if( itcp_poll( ) == -1 ){ //tcp监听阻塞函数,负责接收客户端的链接请求,
sleep( 5 );
continue ;
}
memset( &semops, 0, sizeof( struct sembuf ) );
semops.sem_num = 0 ;
semops.sem_op = 1 ;
semops.sem_flg = SEM_UNDO ;
semop( semid2, ( struct sembuf * )&semops, 1 ) ;
rc = semctl( semid2, 0, GETVAL, 0 );
fprintf( stderr, "rc=[%d]ADDn", rc);
if (rc>30 //预期想通过同一时段并发的进程不超过30(使用信号灯跟踪)
{
fprintf( stderr, "rc>30n");
itcp_clear( );
continue; //不产生子进程,直接退出
}
switch( fork( ) ){
case 0 :
fprintf( stderr, "CHILDREN DEALn");
doClient( ); //子进程处理函数,处理具体交易,通讯时间可能较长
fprintf( stderr, "doClient OVERn");
itcp_clear( );
memset( &semops, 0, sizeof( struct sembuf ) );
semops.sem_num = 0 ;
semops.sem_op = -1 ;
semops.sem_flg = SEM_UNDO ;
semop( semid2, ( struct sembuf * ) &semops, 1 ) ;
rc = semctl( semid2, 0, GETVAL, 0 );
fprintf( stderr, "rc=[%d]DELETEn", rc);
exit(0);
default:
fprintf( stderr, "default DEALn");
itcp_clear( );
break;
}
}
上述server程序,本意想通过信号灯控制并发进程数不超过30,即doClient未退出的时候信号灯数量继续+1,退出的话信号灯-1,实际跟踪发现每次执行顺序都是
rc=[1]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[0]DELETE
rc=[2]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[1]DELETE
rc=[3]ADD
CHILDREN DEAL
default DEAL
START
doClient OVER
rc=[2]DELETE
问题就是不论doClient处理函数是否返回,"ADD"对应的信号灯值不会因为"DELETE"的处理完成而同步,不知道是否因为父子进程完全继承的原因,子进程继承了上一主继承的所有特性,子进程的修改不会映射到父进程?是否因为父子进程权限修改原因?而且上述处理在doclient一直堵塞的情况未退出的情况下今后也会堆积累加到30,还是不符合我需求的只判断某一时段同时并发进程树不超过30的需求,烦请大家指点,谢谢大家了。同事细听是否semop的参数也会导致,"ADD"与"DELETE"处理不能同步处理同一semid,时间紧迫,有知道的兄弟们帮忙了,再次感谢!
|
貌似采用信号灯集的程序不多啊,好久好久没用过信号灯啦。 LZ的程序好像采用计数信号量,可以解决吧。
|
还可以看看:
http://www.cppblog.com/prayer/archive/2009/03/05/75632.html
http://www.cppblog.com/prayer/archive/2009/03/05/75632.html
|
这个是使用 sem 的工具程序,非常完整,主要位于 tools/radcommon.c :
http://oss.oracle.com/projects/rasta/dist/files/rasta-0.1.4.tar.gz
http://oss.oracle.com/projects/rasta/dist/files/rasta-0.1.4.tar.gz
|
mark
|
ding
|
信号灯是二元的信号量.....