C /中断系统调用/前叉与线程 [英] c / interrupted system call / fork vs. thread

查看:105
本文介绍了C /中断系统调用/前叉与线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一个问题与线程执行,那就是怪我。也许有些你可以向我解释,将是巨大的。

I discovered an issue with thread implementation, that is strange to me. Maybe some of you can explain it to me, would be great.

我的工作有点像代理,超过的eth0接收数据包,并将其发送至ATH0(无线)到另一台机器这是做完全一样的事情的程序(在不同的机器上运行)。其实我一点也不知道是什么原因造成我的问题,那是因为我是新来的一切,Linux和C语言编程。

I am working on something like a proxy, a program (running on different machines) that receives packets over eth0 and sends it through ath0 (wireless) to another machine which is doing the exactly same thing. Actually I am not at all sure what is causing my problem, that's because I am new to everything, linux and c programming.

我开始两个线程,


  • 一个在eth0传入数据包侦听(插座)并将其发送出去,通过ATH0(也插座)

  • 和其他线程正在监听ATH0并通过eth0发送。

如果我使用线程,我得到这样一个错误:

If I use threads, I get an error like that:

sh-2.05b# ./socketex 
Failed to send network header packet.
: Interrupted system call

如果我使用fork(),该程序正常工作。
有人可以解释这种行为对我?

If I use fork(), the program works as expected. Can someone explain that behaviour to me?

为了表明这里的发送者来实施其code片断:

Just to show the sender implementation here comes its code snippet:

while(keep_going) {
    memset(&buffer[0], '\0', sizeof(buffer));

    recvlen = recvfrom(sockfd_in, buffer, BUFLEN, 0, (struct sockaddr *) &incoming, &ilen);
    if(recvlen < 0) {
        perror("something went wrong / incoming\n");
        exit(-1);
    }

    strcpy(msg, buffer);
    buflen = strlen(msg);

    sentlen = ath_sendto(sfd, &btpinfo, &addrnwh, &nwh,  buflen, msg, &selpv2, &depv);

    if(sentlen == E_ERR) {
        perror("Failed to send network header packet.\n");
        exit(-1);
    }
}

更新:我的主文件,无论是启动线程或进程(叉)

UPDATE: my main file, starting either threads or processes (fork)

int main(void) {

port_config pConfig;

memset(&pConfig, 0, sizeof(pConfig));
pConfig.inPort = 2002;
pConfig.outPort = 2003;

pid_t retval = fork();

if(retval == 0) {
    // child process
    pc2wsuThread((void *) &pConfig);
} else if (retval < 0) {
    perror("fork not successful\n");
} else {
    // parent process
    wsu2pcThread((void *) &pConfig);
}

/*
wint8 rc1, rc2 = 0;

pthread_t pc2wsu;
pthread_t wsu2pc;

rc1 = pthread_create(&pc2wsu, NULL, pc2wsuThread, (void *) &pConfig);
rc2 = pthread_create(&wsu2pc, NULL, wsu2pcThread, (void *) &pConfig);

if(rc1) {
    printf("error: pthread_create() is %d\n", rc1);
    return(-1);
}

if(rc2) {
    printf("error: pthread_create() is %d\n", rc2);
    return(-1);
}

pthread_join(pc2wsu, NULL);
pthread_join(wsu2pc, NULL);
*/
return 0;
}

帮助?

更新 05/30/2011

update 05/30/2011

-sh-2.05b# ./wsuproxy 192.168.1.100
mgmtsrvc
mgmtsrvc
Failed to send network header packet.
: Interrupted system call
13.254158,75.165482,DATAAAAAAmgmtsrvc
mgmtsrvc
mgmtsrvc

仍然获得中断的系统调用,因为你可以在上面看到。
我封锁了所有的信号如下:

Still get the interrupted system call, as you can see above. I blocked all signals as followed:

sigset_t signal_mask;
sigfillset(&signal_mask);
sigprocmask(SIG_BLOCK, &signal_mask, NULL);

这两个线程工作在同一个接口,但在不同的端口。这个问题似乎仍然会出现在同一个地方(请找到它在第一code段)。我不能更进一步,还没有对如何解决这个问题足够的知识。也许你们中的一些可以帮助我在这里再次。

The two threads are working on the same interfaces, but on different ports. The problem seems to appear still in the same place (please find it in the first code snippet). I can't go further and have not enough knowledge of how to solve that problem. Maybe some of you can help me here again.

先谢谢了。

推荐答案

EINTR 本身并不表示错误。这意味着您的过程中接收的信号,而这是在 SENDTO 系统调用,而系统调用没有发送任何数据(这很重要)。

EINTR does not itself indicate an error. It means that your process received a signal while it was in the sendto syscall, and that syscall hadn't sent any data yet (that's important).

您可以重试在这种情况下发送,可是个好东西是要弄清楚什么引起的信号中断。如果这是可重复的,请尝试使用 strace的

You could retry the send in this case, but a good thing would be to figure out what signal caused the interruption. If this is reproducible, try using strace.

如果你是一个发送信号,好了,你知道该怎么做: - )

If you're the one sending the signal, well, you know what to do :-)

请注意在Linux上,您可以收到 EINTR SENDTO (以及其他一些功能),即使你的避风港'T自己安装的处理程序。这可能发生,如果:

Note that on linux, you can receive EINTR on sendto (and some other functions) even if you haven't installed a handler yourself. This can happen if:

  • 停止进程(通过SIGSTOP为例)并重新启动(与SIGCONT)
  • 您已经设置了插座(通过SO_SNDTIMEO)上发送超时

  • the process is stopped (via SIGSTOP for example) and restarted (with SIGCONT)
  • you have set a send timeout on the socket (via SO_SNDTIMEO)

    查看 信号(7) 手册页(最底部)的更多细节。

    See the signal(7) man page (at the very bottom) for more details.

    所以,如果你是暂停你的服务(或者别的什么东西),即 EINTR 预计,你应该重新启动电话。

    So if you're "suspending" your service (or something else is), that EINTR is expected and you should restart the call.

    这篇关于C /中断系统调用/前叉与线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆