当通过cgo通过golang程序调用时,sigsuspend不会返回

时间:2016-02-23 06:20:43

标签: go signals cgo

我正在使用golang开展一个项目。该项目调用LSF的C API(作业调度程序https://en.wikipedia.org/wiki/Platform_LSF)。一些API在与LSF系统通信时调用sigsuspend()。

在测试期间,我发现这些API永远不会返回。但是当被C程序调用时它们工作正常。因此,我编写了一个简单的测试程序,如下所示(基于Go: Get signal origin: - ))

测试程序证实了我的发现。它打印“sigsuspend之前”和“xxxx发送”,但从不打印“sigsuspend之后”。

有人可以点亮吗?如何使这些API在golang程序中工作就像被C程序调用一样?

package main

/*
#include <stdio.h>
#include <signal.h>
#include <string.h>

struct sigaction old_action;
void handler(int signum, siginfo_t *info, void *context) {
    printf("Sent by %d\n", info->si_pid);
}

void test() {
    sigset_t pauseMask;
    struct sigaction action;

    sigaction(SIGUSR1, NULL, &action);
    memset(&action, 0, sizeof action);
    sigfillset(&action.sa_mask);
    action.sa_sigaction = handler;
    action.sa_flags = SA_SIGINFO | SA_ONSTACK;
    sigaction(SIGUSR1, &action, &old_action);
    sigemptyset(&pauseMask);
    printf("before sigsuspend \n");
    sigsuspend(&pauseMask);
    printf("after sigsuspend \n");
}
*/
import "C"

import (
    "os"
    "syscall"
    "time"
)

/* https://stackoverflow.com/questions/30219751/golang-get-signal-origin */
func main() {
    go C.test()
    pid := os.Getpid()
    for {
        syscall.Kill(pid, syscall.SIGUSR1)
        time.Sleep(time.Second * 5)
    }
}

由于

1 个答案:

答案 0 :(得分:0)

根本原因是在多线程程序中,为了允许sigsuspend返回,我们必须用指定的信号阻塞所有其他线程。但是在golang中,我们无法配置golang的管理线程的sigmask。

详情请参阅以下链接

https://groups.google.com/forum/#!topic/golang-nuts/sYo0iGfkVRg