【发布时间】:2015-11-11 03:13:47
【问题描述】:
这是一个任务,我们必须在没有 pthread 的情况下进行多线程。在每个线程中执行的代码计算 0 和输入整数参数之间的数字之和。到目前为止,该程序仅在使用单个线程时运行良好,但在尝试创建多个线程时出现分段错误。
我从几个来源获得了一些代码并对其进行了修改以获得以下内容:
#define _GNU_SOURCE
#include <malloc.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
//Source for threading outline: http://www.evanjones.ca/software/threading.html
// 64kB stack
#define FIBER_STACK 1024*64
struct sum_runner_struct {
long long limit;
long long answer;
};
// The child threads will execute this function
int threadFunction( void* argument )
{
struct sum_runner_struct *arg_struct = (struct sum_runner_struct*) argument;
long long sum = 0;
long long i = 0;
//Calculate the sum of numbers between 0 and input argument
for (i; i <= arg_struct->limit; i++) {
sum+=i;
}
arg_struct->answer = sum;
printf( "child thread exiting\n" );
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("Wrong number of args\n");
exit(-1);
}
int num_args = argc - 1;
struct sum_runner_struct args[num_args];
void* stack;
//Thread IDs
pid_t pids[num_args];
// Allocate the stack
stack = malloc( FIBER_STACK );
if ( stack == 0 )
{
perror( "malloc: could not allocate stack" );
exit( 1 );
}
printf( "Creating child threads\n" );
int i = 0;
for (i; i < num_args; i++) {
args[i].limit = atoll(argv[i + 1]);
// Call the clone system call to create the child threads
pids[i] = clone( &threadFunction, (char*) stack + FIBER_STACK,
SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, &args[i] );
if ( pids[i] == -1 )
{
perror( "clone" );
exit( 2 );
}
}
int j = 0;
for (j; j < num_args; j++) {
// Wait for the child threads to exit
pids[j] = waitpid( pids[j], 0, 0 );
//Prints the answers that were computed in the child threads
printf("Sum is %lld\n", args[j].answer);
if ( pids[j] == -1 )
{
perror( "waitpid" );
exit( 3 );
}
}
// Free the stack
free( stack );
printf( "Child threads returned and stack freed.\n" );
return 0;
}
使用 gdb 调试,程序执行到第 70 行,此时线程被创建:
pids[i] = clone( &threadFunction, (char*) stack + FIBER_STACK,
SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, &args[i] );
然后当我走过它时,我得到了这个:
70 pids[i] = clone( &threadFunction, (char*) stack + FIBER_STACK,
(gdb) s
Detaching after fork from child process 29143.
child thread exiting
Detaching after fork from child process 29144.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
同样,这只发生在尝试创建多个线程时。该程序仅使用单个线程按预期工作。
任何帮助将不胜感激!
【问题讨论】:
标签: c multithreading