多线程创建问题

zhangyifei216
博客专家认证
2014-11-12 10:46:35
pthread_t *p p = (pthread_t *)malloc(num*sizeof(pthread_t))
然后for循环创建线程,在创建线程的过程中如果num不是特别大的话,是没有什么问题的,我这里设置成

500没有问题,大于500后就会出现段错误,我调试了core dump文件,内容如下:
warning: Corrupted shared library list: 0x7f329f0aa9f8 != 0x7f31bceb0700
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./a.out -c 500 http://www.baidu.com/index.php'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __tsearch (key=key@entry=0x7f3205f416f8, vrootp=vrootp@entry=0x7f3211f5a728,
compar=compar@entry=0x7f329e9c04a0 <known_compare>) at tsearch.c:251
251 tsearch.c: No such file or directory.

但是如果我要是在for循环创建线程的时候sleep(1)秒后就没有啥问题了,但是每次sleep(1)秒这样创建

线程太慢,另外一种情况就是如果改成pthread_t p[num]数组的形式然后for循环创建多线程就没有任何
问题了。 不知道有谁遇见过这样的问题。
...全文
520 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2014-11-13
  • 打赏
  • 举报
回复
在看6L和你9L的说法,主要还是你的bench有问题。
ForestDB 2014-11-13
  • 打赏
  • 举报
回复
其实是应该都有问题,只是刚好数组形式的没有发作而已,看bt,感觉你的入口函数中是不是调用了非线程安全的东西?
zhangyifei216 2014-11-13
  • 打赏
  • 举报
回复
coredump的bt栈信息

(gdb) bt
#0  __tsearch (key=key@entry=0x7f3205f416f8, 
    vrootp=vrootp@entry=0x7f3211f5a728, 
    compar=compar@entry=0x7f329e9c04a0 <known_compare>) at tsearch.c:251
#1  0x00007f329e9c10af in __GI___nss_lookup_function (ni=0x7f3211f5a700, 
    fct_name=fct_name@entry=0x7f329ea234e8 "gethostbyname_r")
    at nsswitch.c:468
#2  0x00007f329e9c15fe in __GI___nss_next2 (ni=ni@entry=0x7f3205f417c0, 
    fct_name=fct_name@entry=0x7f329ea234e8 "gethostbyname_r", 
    fct2_name=fct2_name@entry=0x0, fctp=fctp@entry=0x7f3205f417d0, 
    status=<optimized out>, all_values=all_values@entry=0)
    at nsswitch.c:282
#3  0x00007f329e9b1799 in __gethostbyname_r (
    name=name@entry=0x603440 <hostname> "www.baidu.com", 
    resbuf=resbuf@entry=0x7f329ec668a0 <resbuf>, 
    buffer=0x24f3030 "\377\002", buflen=1024, 
    result=result@entry=0x7f3205f41850, 
    h_errnop=h_errnop@entry=0x7f3205f41840) at ../nss/getXXbyYY_r.c:281
#4  0x00007f329e9b0ef6 in gethostbyname (
---Type <return> to continue, or q <return> to quit---
    name=0x603440 <hostname> "www.baidu.com") at ../nss/getXXbyYY.c:116
#5  0x000000000040111e in Socket ()
#6  0x0000000000401a89 in bench ()
#7  0x00007f329ec71182 in start_thread (arg=0x7f3205f42700)
    at pthread_create.c:312
#8  0x00007f329e99e30d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
zhangyifei216 2014-11-12
  • 打赏
  • 举报
回复
mallco的返回值肯定OK,因为线程以及开始创建了,只是创建了部分线程后出现段错误,
Kai_gai 2014-11-12
  • 打赏
  • 举报
回复
soga!!!!
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
我猜你没判断malloc函数的返回值。
zhangyifei216 2014-11-12
  • 打赏
  • 举报
回复
我的arg是只读的,不需要加锁了把,我也没有free(p) ,我也写过用简单的bench函数代替,想重现问题所在,但是使用简单的bench函数代替就没问题了,但是我搞不懂为什么使用数组的pthread_t就OK了
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
仅供参考
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
    #pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <process.h>
    #include <io.h>
    #define  MYVOID             void
    #define  vsnprintf          _vsnprintf
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
#define ASIZE    200
#define BSIZE    240
#define CSIZE      2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
    int  head;
    int  tail;
    int  size;
    char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
    int i,j,k;
    char binstr[80];

    Lock(&cs_HEX);
    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%03d %04x -",cn,i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            Log("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        Log("%s\n",binstr);
    }
    Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    lent=0;
    Lock(cs);
    if (fbuf->size>=len) {
        lent=len;
        if (fbuf->head+lent>BSIZE) {
            len1=BSIZE-fbuf->head;
            memcpy(buf     ,fbuf->data+fbuf->head,len1);
            len2=lent-len1;
            memcpy(buf+len1,fbuf->data           ,len2);
            fbuf->head=len2;
        } else {
            memcpy(buf     ,fbuf->data+fbuf->head,lent);
            fbuf->head+=lent;
        }
        fbuf->size-=lent;
    }
    Unlock(cs);
    return lent;
}
MYVOID thdB(void *pcn) {
    char        *recv_buf;
    int          recv_nbytes;
    int          cn;
    int          wc;
    int          pb;

    cn=(int)pcn;
    Log("%03d thdB              thread begin...\n",cn);
    while (1) {
        sleep_ms(10);
        recv_buf=(char *)Cbuf;
        recv_nbytes=CSIZE;
        wc=0;
        while (1) {
            pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
            if (pb) {
                Log("%03d recv %d bytes\n",cn,pb);
                HexDump(cn,recv_buf,pb);
                sleep_ms(1);
            } else {
                sleep_ms(1000);
            }
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    Lock(cs);
    lent=len;
    if (fbuf->size+lent>BSIZE) {
        lent=BSIZE-fbuf->size;
    }
    if (fbuf->tail+lent>BSIZE) {
        len1=BSIZE-fbuf->tail;
        memcpy(fbuf->data+fbuf->tail,buf     ,len1);
        len2=lent-len1;
        memcpy(fbuf->data           ,buf+len1,len2);
        fbuf->tail=len2;
    } else {
        memcpy(fbuf->data+fbuf->tail,buf     ,lent);
        fbuf->tail+=lent;
    }
    fbuf->size+=lent;
    Unlock(cs);
    return lent;
}
MYVOID thdA(void *pcn) {
    char        *send_buf;
    int          send_nbytes;
    int          cn;
    int          wc;
    int           a;
    int          pa;

    cn=(int)pcn;
    Log("%03d thdA              thread begin...\n",cn);
    a=0;
    while (1) {
        sleep_ms(100);
        memset(Abuf,a,ASIZE);
        a=(a+1)%256;
        if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
        send_buf=(char *)Abuf;
        send_nbytes=ASIZE;
        Log("%03d sending %d bytes\n",cn,send_nbytes);
        HexDump(cn,send_buf,send_nbytes);
        wc=0;
        while (1) {
            pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
            Log("%03d sent %d bytes\n",cn,pa);
            HexDump(cn,send_buf,pa);
            send_buf+=pa;
            send_nbytes-=pa;
            if (send_nbytes<=0) break;//
            sleep_ms(1000);
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
    InitializeCriticalSection(&cs_HEX );
    InitializeCriticalSection(&cs_BBB );
#else
    pthread_t threads[2];
    int threadsN;
    int rc;
    pthread_mutex_init(&cs_log,NULL);
    pthread_mutex_init(&cs_HEX,NULL);
    pthread_mutex_init(&cs_BBB,NULL);
#endif
    Log("Start===========================================================\n");

    BBB.head=0;
    BBB.tail=0;
    BBB.size=0;

#ifdef WIN32
    _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
    _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
    rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif

    if (!access("No_Loop",0)) {
        remove("No_Loop");
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    while (1) {
        sleep_ms(1000);
        if (No_Loop) break;//
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    sleep_ms(3000);
    Log("End=============================================================\n");
#ifdef WIN32
    DeleteCriticalSection(&cs_BBB );
    DeleteCriticalSection(&cs_HEX );
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_BBB);
    pthread_mutex_destroy(&cs_HEX);
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
还要确保各线程访问arg时加了锁。
mymtom 2014-11-12
  • 打赏
  • 举报
回复
是不是bench函数的问题呀,写个简单的函数代替bench试试
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
        pthread_t *p;
        p = (pthread_t*)malloc(clients*sizeof(pthread_t));
        assert(p);
        //请确保本进程退出前不要free(p)
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
        for(i = 0;i < clients;i++)
        {
                if(pthread_create(&p[i],NULL,bench,(void *)&arg))
                        perror("client %d create failue:",i);
//              usleep(50);
        }

zhangyifei216 2014-11-12
  • 打赏
  • 举报
回复
不太明白您的意思,为什么我使用数组的形式创建pthread_t就没有关系了呢
nice_cxf 2014-11-12
  • 打赏
  • 举报
回复
基本肯定是函数里面越界了把数据破坏了
zhangyifei216 2014-11-12
  • 打赏
  • 举报
回复

        pthread_t p[PTHREAD_MAX];   //这种方式没问题,使用下面的这种指针分配空间就有问题
//      pthread_t *p;
//      p = (pthread_t*)malloc(clients*sizeof(pthread_t));
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
        for(i = 0;i < clients;i++)
        {
                if(pthread_create(&p[i],NULL,bench,(void *)&arg))
                        perror("client create failue:");
                usleep(50);
        }

bench这个函数代码比较多,这里就不贴出来了
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
相关代码请贴全。
ForestDB 2014-11-12
  • 打赏
  • 举报
回复
都有coredump了,上debugger看看调用栈什么的吧。
赵4老师 2014-11-12
  • 打赏
  • 举报
回复
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令

69,992

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧