免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7871 | 回复: 5
打印 上一主题 下一主题

[函数] 请帮看看,线程里sem_wait()函数被中断的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-08-15 15:05 |只看该作者 |倒序浏览
typedef struct sipt_timer_set TimerSet;
struct sipt_timer_set
{
        int numOfTimer;
        //CrlData timerCrl;
        sem_t mutex;

        struct itimerval newitimer;
        struct itimerval olditimer;

        list_t timerList;
};

typedef struct response_Crl_Set
{
        //CrlData timerCrl;
        sipt_list resplist;
        sem_t mutex, nresp;
        int resp_thread_run;
        pthread_t resp_thread;
       
       
       
}RespCrlSet;

//2个全局变量
extern TimerSet *timerset;
extern RespCrlSet *respset;

int
main(int argc, char *argv[])
{

        sipt_signal(  SIGALRM , funSigAlrm ,  0 );

        timerset = sipt_timerSet_new();
        respset = sipt_respSet_new();

        // 启动一个新线程
        sipt_start_resp_thread( respset );
        int i;
        for( i = 0 ; i < 100 ; i ++ )
        {
                sipt_insert_timer( timerset ,  200  );
                usleep( 1000000 );
        }



        sthread_join( &respset->;resp_thread );

}

// 信号处理函数,当收到SIGALRM信号是执行
void
funSigAlrm()
{
        printf( "signal received\n" );
        sem_post( &respset->;nresp );
        int nsig = 0;
        int rval;
        rval = sem_getvalue( &respset->;nresp , &nsig );
        printf( "in sighander nsig = %d rval = %d\n" , nsig , rval );

}

// 线程执行函数
void*
sipt_resp_thread( void *myarg )
{
        //TimerSet *timset = (TimerSet*)myarg;
        TimerSet *timset = timerset;
        RespCrlSet *respset = (RespCrlSet*)myarg;
        TimeVal *tim = NULL;
        int nsig = 0;
        int nresp = 0;
       
        while(1)
        {
                int oo;
                oo = sem_wait( &respset->;nresp); // sem_wait函数被中断 errno 被设置为4
                sem_wait( &respset->;mutex );
                printf( "oo = %d  , EAGAIN = %d EINTR = %d\n" , oo , EAGAIN , EINTR );
                if( errno )
                {       
                        perror( "sem_wait() fail: " );
                        errno = 0;
                }

                if( respset->;resp_thread_run != 1 )
                        break;
               
                //do something to response
                int rval;
                rval = sem_getvalue( &respset->;nresp , &nsig );
                printf( "in thread  nsig = %d ,  rval = %d\n" , nsig , rval );       
                nresp++;
                printf( "Send response[%d] \n" , nresp );
                sem_post( &respset->;mutex );

                sem_wait( &timset->;mutex );
                //printf( "timer : %d\n" , timset->;numOfTimer );
                tim = (TimeVal*)timset->;timerList.node->;element;
                sipt_list_remove( &timset->;timerList ,  0 );
                timset->;numOfTimer--;
                gettimeofday( tim , NULL );
                if( timset->;numOfTimer >; 0 )
                {
                        set_itimerval2( &timset->;newitimer , 0 , 0 , tim ,
                                        (TimeVal *) timset->;timerList.node->;element );
                        setitimer( ITIMER_REAL , &timset->;newitimer , &timset->;olditimer );
                }
                sem_post( &timset->;mutex );

                sfree( tim );
                tim = NULL;                printf( "finish one process\n" );
        }
        sem_post( &respset->;mutex );

}


程序是这样执行的,但程序收到一条消息是,将延迟1段时间然后发出response。于是我在收到消息时设置一个时间,然后设置定时器,当消息到达时发SIGALRM信号,信号出来函数收到信号后sem_post( &respset->;nresp ); ,nresp的值将加1,而另一个线程阻塞在sem_wait负责发response,当信号处理函数发n次sem_post(),nrep的值将加n,线程sem_wait()将减1,发一次response,循环使得发出相应次数的response。现在 问题在于sem_wait()只正常执行一次,第2次就被中断,返回-1.


执行结果
size of timer list = 1
signal received
in sighander nsig = 1 rval = 0
oo = 0  , EAGAIN = 11 EINTR = 4
errno = 0
in thread  nsig = 0 ,  rval = 0
Send response[1]
size of timer list = 2
finish one process
signal received
in sighander nsig = 1 rval = 0
oo = -1  , EAGAIN = 11 EINTR = 4 //sem_wait 被中断了
errno = 4
sem_wait() fail: : Interrupted system call //perror()的输出
in thread  nsig = 1 ,  rval = 0
Send response[2]
finish one process
oo = 0  , EAGAIN = 11 EINTR = 4
errno = 0
in thread  nsig = 0 ,  rval = 0
Send response[3]
Segmentation fault

论坛徽章:
0
2 [报告]
发表于 2005-08-15 15:24 |只看该作者

请帮看看,线程里sem_wait()函数被中断的问题

我在执行线程里把 SIGALRM 屏蔽了好像就没有再被中断了,有个问题,信号mask不是进程相关的吗?我的主线程里的SIGALRM信号并没有被屏蔽信号处理函数还是能接收到信号,在sigprocmask()是在另一个线程里调用的

论坛徽章:
0
3 [报告]
发表于 2005-08-15 16:34 |只看该作者

请帮看看,线程里sem_wait()函数被中断的问题

在funSigAlrm() 中再加一次 sipt_signal(  SIGALRM , funSigAlrm ,  0 );  呢?

论坛徽章:
0
4 [报告]
发表于 2005-08-16 09:34 |只看该作者

请帮看看,线程里sem_wait()函数被中断的问题

不起作用,sipt_signal()里是用sigaction()实现,应该不用重新设一遍


[quote]原帖由 "天狼星"]在funSigAlrm() 中再加一次 sipt_signal(  SIGALRM , funSigAlrm ,  0 );  呢?[/quote 发表:

论坛徽章:
0
5 [报告]
发表于 2006-12-26 09:21 |只看该作者
这是在 sem_wait 内部没有屏蔽 EINTR 导致, 导致在 sem_wait 所等待的信号量没有满足时也退出等待.
请看看这篇帖子.

http://www.topjoy.net/bbs/viewthread.php?tid=123

论坛徽章:
0
6 [报告]
发表于 2006-12-26 12:40 |只看该作者
rt = ...;
while ( rt == -1 && errno == EINTR )
  rt = ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP