相关疑难解决方法(0)

哪个线程处理信号?

我有2个线程(thread1和thread2).我有信号处理SIGINT.每当SIGINT发生线程2应该处理信号时.为此,我写了下面的程序

void sig_hand(int no)                  //signal handler
{
    printf("handler executing...\n");
    getchar();
}

void* thread1(void *arg1)              //thread1 
{
    while(1) {
            printf("thread1 active\n");
            sleep(1);
    }
}

void * thread2(void * arg2)           //thread2
{
    signal(2, sig_hand);
    while(1) {
    printf("thread2 active\n");
    sleep(3);
    }
}

int main()
{
    pthread_t t1;
    pthread_t t1;

    pthread_create(&t1, NULL, thread1, NULL);
    pthread_create(&t2, NULL, thread2, NULL);
    while(1);
}
Run Code Online (Sandbox Code Playgroud)

我编译并运行该程序.每1秒"thread1 active"正在打印,并且每3秒"thread2 active"正在打印.

现在我生成了SIGINT.但它上面打印"thread1 active"和"thread2 active"消息.我再次生成SIGINT,现在每3秒只有"thread2 active"消息正在打印.我再次生成SIGINT,现在所有线程都被阻止了.

所以我理解,第一次主线程执行信号处理程序.第二次thread1执行处理程序,最后thread2执行信号处理程序.

我怎样才能编写代码,就像信号发生时一样,只有thread2必须执行我的信号处理程序?

c linux multithreading signals pthreads

11
推荐指数
2
解决办法
1万
查看次数

在多线程程序中捕获SIGSEGV和SIGFPE等信号

我正在尝试为在linux上运行的程序编写多线程日志记录系统.

在主程序线程中调用日志记录系统会将包含要记录的数据的数据结构推送到FIFO队列中.专用线程选择队列的数据并输出数据,而程序主线程继续其任务.

如果主程序导致SIGSEGV或其他信号被引发,我需要在终止之前确保队列为空.

我的计划是使用pthread_sigmask http://man7.org/linux/man-pages/man3/pthread_sigmask.3.html阻止除一个线程之外的所有信号,但是在http://man7.org上读取信号列表/linux/man-pages/man7/signal.7.html我注意到:

可以为整个过程(例如,当使用kill(2)发送时)或针对特定线程(例如,某些信号,例如SIGSEGV和SIGFPE,>生成的信号)生成(并因此待决)信号执行特定机器语言指令的步骤是线程定向的,使用pthread_kill(3)的特定线程的信号也是如此.

如果我在所有线程上阻塞SIGSEGV但是一个专用于捕获信号的线程,那么它会捕获由不同线程引发的SIGSEGV吗?

在Linux中发现了使用多个线程进行信号处理的问题,但我对于哪些信号是特定于线程以及如何捕获它们一无所知.

c++ linux multithreading posix

6
推荐指数
1
解决办法
2238
查看次数

为单个线程创建信号处理程序

我想知道是否sigaction会为调用线程或整个进程创建一个信号处理程序。如果它解除阻塞信号并为整个进程创建信号处理程序,那么我如何确保只有一个线程会使用该信号处理程序并让其他线程阻塞该信号。

就我而言,我希望单个线程在警报信号消失时调用信号处理程序,而其他线程则简单地阻止它。


void alarmSigHandler(int signo){

}

void* alarm_thread_start_routine(void *arg){

    // Perform some tasks

}


int main(){

    // Main thread start

    /* Unblock alarm signal */
    /* Assign signal handler for alarm signal */

    /* Launch alarm signal handler thread */

    /* Block alarm signal with pthread_sigmask */

    /* Do something */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

http://vip.cs.utsa.edu/classes/cs3733f2013/notes/SignalsAndThreads.html

如果将信号发送到线程程序,则任何线程都可以处理该信号。

每个线程都会继承进程信号掩码,但每个线程都有自己的信号掩码,可以使用 pthread_sigmask 进行修改。

sigprocmask 不应在线程环境中使用,但可以在创建线程之前使用。

在多线程环境中处理信号的最简单方法是有一个专用于信号处理的线程。

涉及信号安全的问题可以使用sigwait来处理:

The main process blocks all signals before creating any threads.
No signal handlers are set …
Run Code Online (Sandbox Code Playgroud)

c unix posix signals signal-handling

5
推荐指数
1
解决办法
3870
查看次数

在Linux/GCC下将NULL指针访问转换为C++异常

有没有办法将NULL指针访问转换为Linux下的C++异常?类似于Java中的NullPointerException.我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法找出此NULL指针访问):

class NullPointerException {};

void accessNullPointer(char* ptr) {
    *ptr = 0;
}

int main() {
    try {
        accessNullPointer(0);
    } catch (NullPointerException&) {
        return 1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不期望任何标准的方法,因为C++下的NULL指针访问是未定义的 - 行为,只是想知道如何在x86_64 Linux/GCC下完成它.

我做了一些非常原始的研究,有可能:

  1. 当在Linux下访问NULL指针时,将生成SIGSEGV.
  2. 在SIGSEGV处理程序内部,程序的内存和寄存器信息将可用(如果sigaction()用于注册信号处理程序).如果程序被反汇编,也可以使用导致SIGSEGV的指令.
  3. 修改程序的内存和/或注册,并创建/伪造异常实例(可能通过调用低级展开库函数,如_Unwind_RaiseException等)
  4. 最后从信号处理程序返回,希望程序启动一个C++堆栈展开过程就像抛出正常异常一样.

以下是GCC手册页的引用(-fnon-call-exceptions):

生成允许捕获指令以抛出异常的代码.请注意,这需要在任何地方都不存在的特定于平台的运行时支持.此外,它只允许捕获指令抛出异常,即内存引用或浮点指令.它不允许从诸如"SIGALRM"之类的任意信号处理程序抛出异常.

看来这个"特定于平台的运行时"正是我想要的.任何人都知道这样的Linux/x86_64运行时?或者如果没有这样的运行时已经存在,请给我一些关于如何实现这样的运行时的信息?

我希望该解决方案也适用于多线程程序.

c++ linux gcc exception stack-unwinding

5
推荐指数
1
解决办法
417
查看次数

线程之间的setjmp/longjmp处理超时

我正在将软件从嵌入式计算机移植到Linux机器上.(Ubuntu 14.04或Raspbian(raspberry pi))

原始程序使用setjmp/longjmp来处理超时和CTRL + C事件.它运行在具有单个主(一个线程)的微控制器上.

我正在尝试使用线程(pthreads)时有类似的行为.

我的想法是我想要超时或CTRL + C来重启无限循环.

原始代码正在执行类似下面的代码.我不介意用别的东西放弃setjmp/longjmp.(例如:try/catch或signal或pthread_kill,条件变量等.)

知道如何用C/C++实现类似的行为吗?

这是代码似乎部分工作,可能不推荐/破坏:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <setjmp.h>

// Define
#define TICK_NS_TIME (10000000)                                                 // 0.01 sec = 10 ms (100 times per second)
#define NS_PER_SEC   (1000000000)                                               // Nano sec per second.
#define TICK_PER_SEC (NS_PER_SEC/TICK_NS_TIME)                                  // Number of tick per second (Ex:100)
#define TIMEOUT_COUNT (30*TICK_PER_SEC)                                         // 30 seconds timeout (with 100 tick per second)

// Env set/long jmp
#define ENV_SZ (2)
#define …
Run Code Online (Sandbox Code Playgroud)

c multithreading pthreads longjmp setjmp

3
推荐指数
1
解决办法
1127
查看次数