【发布时间】:2019-07-04 09:08:03
【问题描述】:
我正在 linux 上用 C 语言开发一个简单的程序,其中有一个线程检查自程序开始以来经过的时间,当它们经过 10 秒时,发送一个结束信号(例如 SIGINT 或 SIGTERM)到主程序,什么应该让它以干净的方式结束。
最后附上C程序。
执行thread_kill调用时,会发生Segmentation fault。
用gdb运行这个程序的结果如下:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff77f2700 (LWP 25472)]
__pthread_kill (threadid=25466, signo=2) at
../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:42
42 ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill (threadid=25466, signo=2) at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:42
#1 0x0000000000400a1e in ThreadRoutine (number=1) at program_16b.c:46
#2 0x00007ffff7bc4184 in start_thread (arg=0x7ffff77f2700) at pthread_create.c:312
#3 0x00007ffff78f103d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)
我的代码有什么问题?
program.c:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#define _REENTRANT
struct timeval begin, end;
void siginthandler(int param)
{
printf("User has pressed Ctrl + C\n");
}
void *ThreadRoutine(int number)
{
long microseconds;
printf ("[thread %d] pthread_self = %d, getpid = %d, getppid = %d\n",
number, pthread_self(), getpid(), getppid());
while(1) // loop forever
{
printf("thread type 1 (%d) running\n",number);
if (number == 1)
{
gettimeofday(&end, NULL);
microseconds = (end.tv_sec - begin.tv_sec) * 1000000 + (end.tv_usec - begin.tv_usec);
printf ("Microseconds from starting time = %ld\n", microseconds);
if (microseconds >= 10000000)
{
printf("Killing parent process after 10 seconds from starting.\n");
pthread_kill(getppid(), SIGINT);
}
}
sleep(number); // sleep for number seconds, value passed as a parameter.
}
}
int main(void)
{
int t;
pthread_t tid[13]; // an array to keep track of the threads
// To create a detached thread.
pthread_attr_t attr; // thread attribute
// To call to pthread_attr_get...
int rc, val;
struct sched_param sp;
size_t v;
void *stkaddr;
signal(SIGINT, siginthandler);
printf ("[parent] pid = %d\n", getpid());
gettimeofday(&begin, NULL);
for (t=1; t<3; t++)
{
pthread_create(&tid[t],NULL,(void *)ThreadRoutine,(int *)t);
printf ("Created thread %d with id=%d\n", t, (int)tid[t]);
}
sleep(30);
return 0;
}
程序运行时的屏幕输出:
[parent] pid = 18994
Created thread 1 with id=1463871232
[thread 1] pthread_self = 1463871232, getpid = 18994, getppid = 25402
thread type 1 (1) running
Microseconds from starting time = 175
[thread 2] pthread_self = 1455478528, getpid = 18994, getppid = 25402
thread type 1 (2) running
Created thread 2 with id=1455478528
thread type 1 (1) running
Microseconds from starting time = 1000319
thread type 1 (2) running
thread type 1 (1) running
Microseconds from starting time = 2000536
thread type 1 (1) running
Microseconds from starting time = 3000722
thread type 1 (2) running
thread type 1 (1) running
Microseconds from starting time = 4000819
thread type 1 (1) running
Microseconds from starting time = 5000997
thread type 1 (2) running
thread type 1 (1) running
Microseconds from starting time = 6001088
thread type 1 (1) running
Microseconds from starting time = 7001264
thread type 1 (2) running
thread type 1 (1) running
Microseconds from starting time = 8001383
thread type 1 (1) running
Microseconds from starting time = 9001556
thread type 1 (2) running
thread type 1 (1) running
Microseconds from starting time = 10001677
Killing parent process after 10 seconds from starting.
Segmentation fault (core dumped)
【问题讨论】:
-
在SEGV之前你得到了什么输出......??
-
在原始问题的 ehd 中添加了整个输出。
-
如果对 thread_kill() 的调用被 exit() 替换,程序将在没有分段错误的情况下完成。这是一个好的解决方案吗?是否可以使用父进程的 PID 来杀死父进程?
-
Ubuntu 18.04 的 pthread_kill() 手册页有这个原型: int pthread_kill(pthread_t thread, int sig);... 注意第一个参数是“threadID”,而不是进程 ID您已通过 getppid() 指定。
-
谢谢,我改用 pthread_self(),程序运行正常。
标签: c linux multithreading segmentation-fault signals