我的程序中存在分段错误错误。我在POSIX C中练习多线程程序。我在FREEBSD系统中运行这些程序。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#define NUM_THREADS 15
void *PrintHello(void *threadid)
{
printf("Hello World from thread: %p \n", threadid);
fflush(NULL);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int rtrn, *i;
pthread_t threads[NUM_THREADS];
for((*i)=0; (*i)<NUM_THREADS; (*i)++)
{
if( pthread_create(&threads[(*i)], NULL, PrintHello, (void *)i) != 0)
{
printf("Error code %d detected while thread %d was being created.", rtrn, *i);
}
}
return 0;
}
我必须将i整数变量转换为指针整数,因为这在编译期间解决了错误(第22行:警告:从不同大小的整数转换为指针)
编译错误已经解决,但现在当我运行程序时,它显示了这个:分段错误:11(核心转储)
可能之前的警告尚未解决,但我不知道如何修复它......
答案 0 :(得分:1)
您需要为变量i
分配内存。现在它是一个指向某处的指针,但你绝对不会欠那段记忆。
之后
i = calloc(1, sizeof(int));
您将拥有一段有效的内存,初始化为0(感谢calloc
)。
另一方面,如果您将通过指针使用i
,则可能会有一个有趣的行为,具体取决于您的操作系统如何启动线程。所有线程都将使用相同的地址,因此其中一些可能会在屏幕上显示相同的值:)如果您想通过线程打印10个不同的数字,请转到0x90
的答案:)
答案 1 :(得分:1)
我做了一些改变:
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 15
void *PrintHello(void *threadid)
{
printf("Hello World from thread: %d \n", *(int *)threadid);
fflush(NULL);
pthread_exit(NULL);
}
static int id[NUM_THREADS];
int main(int argc, char *argv[])
{
int rtrn;
pthread_t threads[NUM_THREADS];
for(int i=0; i<NUM_THREADS; i++) {
id[i] = i;
if (pthread_create(&threads[i], NULL, PrintHello, (void *)&id[i]))
printf("Error code %d detected while thread %d was being created.", rtrn, i);
}
return 0;
}
将输出:
Hello World from thread: 0
Hello World from thread: 1
Hello World from thread: 2
Hello World from thread: 3
Hello World from thread: 4
Hello World from thread: 5
Hello World from thread: 6
Hello World from thread: 7
Hello World from thread: 8
Hello World from thread: 9
Hello World from thread: 10
Hello World from thread: 11
Hello World from thread: 12
Hello World from thread: 13
Hello World from thread: 14
答案 2 :(得分:1)
如果要做的只是将 id 传递给调用线程,可以将隐藏在 void*
参数中,然后执行此操作可移植。使用像intptr_t
这样的整数类型,这是你的平台上“足够容纳数据指针的整数”,我很确定这更接近你想要的。
此外,POSIX要求FILE*
上的stdio函数是线程安全的,所以你可能会丢失fflush()
(这无论如何都没有帮助),不过如果你要搜索为什么会这样,这是不明显的。查看flockfile()
的文档,并注意提及所有在FILE*
上运行的stdio函数(其中printf()
对stdout
执行的操作)的行为应该像调用{{ {1}}和flockfile
获取对流的访问权。)没有关于锁定的原子性的规范(对于你所知道的所有内容,它可以归结为字符,其中案例交错运行,但它应该仍然是安全的。
funlockfile
<强>输出强>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <inttypes.h>
#define NUM_THREADS 15
void *PrintHello(void *threadid)
{
intptr_t id = (intptr_t)threadid;
printf("Hello World from thread: %" PRIiPTR "\n", id);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
intptr_t i=0;
int res;
for(i=0; i<NUM_THREADS; ++i)
{
if( (res = pthread_create(threads+i, NULL, PrintHello, (void *)i)) != 0)
printf("Error code %d detected while thread %" PRIiPTR " was being created.", res, i);
}
// wait for all to complete
for (i=0;i<NUM_THREADS;++i)
pthread_join(threads[i], NULL);
return 0;
}
最后,如果您正在对格式字符串中隐藏的奇怪的Hello World from thread: 0
Hello World from thread: 1
Hello World from thread: 2
Hello World from thread: 3
Hello World from thread: 4
Hello World from thread: 5
Hello World from thread: 6
Hello World from thread: 7
Hello World from thread: 8
Hello World from thread: 9
Hello World from thread: 10
Hello World from thread: 11
Hello World from thread: 12
Hello World from thread: 14
Hello World from thread: 13
进行双重拍摄,那么您应该值得花时间阅读this question and answers。它是使用正确的“%”类型将PRIiPTR
转储为格式化数据的便携式机制。