将睡眠与 Pthread 一起使用时在 C 中出现分段错误

Posted

技术标签:

【中文标题】将睡眠与 Pthread 一起使用时在 C 中出现分段错误【英文标题】:Getting Segmentation Fault in C when using sleep with Pthreads 【发布时间】:2019-04-12 13:28:59 【问题描述】:

我正在使用 PThreads 在 C 中创建一个线程,该线程执行一个在无限循环中运行的函数,并每秒将一些随机 json 字符串打印到控制台中。一开始他打印函数模拟LED的结果没有问题,但在休眠1秒后,我会得到一个分段错误(核心转储)。如果我删除睡眠,我不会得到它并且程序运行正常。为什么我在睡眠时会出现分段错误以及如何解决?

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

char *simulateLED() 
    int temp;
    int luftf;
    char* jsonString;

    time_t t;
    srand((unsigned) time(&t));

    int x=-10, y=50;
    temp=(rand()%((y+1)-x))+x;

    x=2, y=30;
    luftf=(rand()%((y+1)-x))+x;

    printf("%d %d\n", temp, luftf);
    fflush(stdout);

    sprintf(jsonString, "\n\"TEMP\": %d,\n\"HUMI\": %d\n", temp, luftf);

    return jsonString;

void *simAndSendThread(void *param) 
    while(1) 
        printf("%s", simulateLED());
        sleep(1);
    

int main(int argc, char *argv[]) 
    pthread_t thread;

    if(pthread_create(&thread, NULL, simAndSendThread, NULL)) 
        fprintf(stderr, "Error creating thread\n");
        return 1;
    

    if(pthread_join(thread, NULL)) 
        fprintf(stderr, "Error joining thread\n");
        return 2;
    

    pthread_exit(NULL);
    return 0;

【问题讨论】:

您永远不会为 jsonString 赋值。你将它的垃圾值传递给sprintf,这可不好。 【参考方案1】:

正如@DavidSchwartz 所指出的,Segmentation fault (core dumped) 错误的原因与 jsonString 指针有关,该指针当前未初始化(即,未指向任何东西)。因此,sprintf 正在写入随机位置,这有时可能有效,也可能无效。

为了修复它,你可以在声明jsonString变量的时候静态分配空间,比如:

...
char jsonString[256];
...

这意味着您可以拥有最多255 个字符的字符串(1\0 保留的额外字符)。或者,您可以使用malloc 动态分配空间:

...
char *jsonString = (char *)malloc(sizeof(char) * 256);

// Your code here

free(jsonString);
...

在这种情况下,您必须记住在函数结束时使用free 释放分配,否则会泄漏内存。如果您还没有了解动态内存,请参阅When and why to use malloc?。

P.S.:如果您使用的是 Linux,我强烈建议您在遇到与内存相关的错误时使用 valgrind。该工具很可能会提示您在哪里犯了错误。更多信息请查看Valgrind Quick Start Guide。

【讨论】:

【参考方案2】:

您还没有为jsonString 分配内存并且仍在尝试执行sprintf 并在返回print 之后进行

试试这个

char* jsonString;
    jsonString = malloc( 1024 );

别忘了free 完成后,您正在使用while(1),如果您不使用free,您很有可能会遇到内存不足 很快就会出错。

如果您enable full warnings,您应该收到warning message for uninitialized variable,最终可以避免所有的崩溃。

【讨论】:

以上是关于将睡眠与 Pthread 一起使用时在 C 中出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

从 pthread 调用 sleep() 是不是会使线程进入睡眠状态或进程?

findViewById() 在与合并标签一起使用时在包含标签上抛出空指针

当 sleep() 不能很好地与警报一起工作时,我还能做啥“睡眠”?

pthread_mutex_lock和EAGAIN

NSOperationQueue 与 pthread 优先级

pthread为啥规定cond要和mutex一起使用