linux malloc 多线程,多线程中的free malloc怎么用

多线程中的free malloc怎么用

(2012-04-11 01:05:13)

标签:

多线程

杂谈

多线程中的free malloc怎么用 本帖最后由 lonerwolf 于 2010-12-06 18:36 编辑

{:3_183:}反复检查程序感觉写的没问题,但是我主线程malloc的一个空间在其他线程free出现了段错误,是不是两个线程的堆不是共享的??可是看地址是一样的{:3_190:}我该怎么办

搜索出来发现线程的free只能free自己的堆,不能对进程共享堆释放.....有没有能释放共享堆的系统调用.............{:3_183:}自己又写了个测试发现主线程malloc其他线程可以释放......上面搜索出来的好像是WINDOW的....

我其实就是用ET

多线程,用stru_socket结构来解决数据包切片问题,用一个数组指针保存这个结构体,用socket的文件描述符来索引,现在问题是,主线程接受到读事件,把stru_socket结构放入队列,处理线程取出的函数里发生错误,就是free那里段错误

崩溃的多线程................真难调试.........虽然可以通过了

typedef struct _queue_node 队列头文件

{

stru_socket *strusocketptr;

struct _queue_node *next;

} queue_node;

typedef struct _queue_list

{

queue_node *front;

queue_node *rear;

} queue_list;

void initqueue( queue_list *queuelistptr);

void pushbackqueue( queue_list *queuelistptr, stru_socket

*strusocketptr);

stru_socket *popfrontqueue( queue_list *queuelistptr);

int isemptyqueue( queue_list queuelist);

#include "queue.h"

这是放SOCKET结构用的队列 处理

void initqueue( queue_list *list)

{

list->front = list->rear =

NULL;

}

void pushbackqueue( queue_list *queuelistptr, stru_socket

*strusocketptr)

{

queue_node *newentry;

newentry = (queue_node*)malloc( sizeof( queue_node));

if( newentry == NULL)

{

perror("malloc failed");

exit(1);

}

newentry->strusocketptr = strusocketptr;

newentry->next = NULL;

if ( queuelistptr->rear == NULL)

{

queuelistptr->front =

queuelistptr->rear = newentry;

}

else

{

(queuelistptr->rear)->next =

newentry;

queuelistptr->rear = newentry;

}

}

stru_socket *popfrontqueue( queue_list *queuelistptr)

{

if( queuelistptr->front == NULL)

{

printf("the queuelist is empty.so can't pop the

front elem\n");

exit(1);

}

if( queuelistptr->front ==

queuelistptr->rear)//只有1个元素时

{

stru_socket *temp =

queuelistptr->front->strusocketptr;

//暂存结构指针

free( queuelistptr->front); //释放前面链表队列malloc的结构

这里是出错点!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

queuelistptr->front =

queuelistptr->rear = NULL;

return temp;

}

else

{

stru_socket *temp =

queuelistptr->front->strusocketptr;

queue_node *p = queuelistptr->front;

queuelistptr->front =

(queuelistptr->front)->next;

free(p);

return temp;

}

}

int isemptyqueue( queue_list queuelist)

{

if( queuelist.front == NULL)

return 1;

return 0;

}

enum STRUSOCKETSTATE

这是socketio.h,定义了结构,返回值,还有ET模式下通过前2字节判断长度来读写的函数

{

REMAIN,

CLOSE,

NORMAL

};

enum IORETURNTYPE

{

SIDECLOSE = -10,

DATAREMAIN,

NODATA

};

typedef struct _stru_socket

{

int socketfd;

int state; //NORMAL为正常,REMAIN为数据包被切片,被切片的数据保存在下面那个remainbuff里

int remainsize;

int remainoffset;

unsigned char *remainbuff;

} stru_socket;

int et_sendmsgbysize( stru_socket strusocket, unsigned char *msg,

int size);

int et_recvmsgbysize( stru_socket strusocket, unsigned char

*recvarray);

#endif

#define SERVER_PORT 20000 这是main

#define EPOLL_SIZE500

#define EPOLLEVENTS_MAXSIZE 500

#define MAXCONNECTS 500

#define THREADNUM 3

#define MAXPACKETSIZE 500

void *dealthread( void *arg);

sem_t newevent;

pthread_mutex_t clientacceptmutex;

queue_list queuelist;

stru_socket *socketarray;

void setnonblock( int sock)

{

int opts;

if ( (opts = fcntl( sock, F_GETFL)) < 0)

{

perror("fcntl(sock,GETFL)");

exit(1);

}

opts = opts | O_NONBLOCK;

if ( fcntl( sock, F_SETFL, opts) < 0)

{

perror("fcntl(sock,SETFL,opts)");

exit(1);

}

}

int main( int argc, char **argv)

{

int servfd, threadnum;

struct sockaddr_in servaddr,cliaddr;

socklen_t clilen = sizeof( cliaddr);

initqueue( &queuelist);

memset( socketarray, 0, (sizeof(stru_socket*))*MAXCONNECTS);

pthread_mutex_init( &clientacceptmutex,

NULL);

sem_init( &newevent, 0 ,0);

pthread_t pid;

for( threadnum = 0; threadnum < THREADNUM;

threadnum++)

{

if( pthread_create( &pid, NULL, dealthread, NULL)

== 0)

{

printf("create thread %d

success\n", threadnum);

}

}

if( ( servfd = socket( AF_INET, SOCK_STREAM, 0)) <

0)

{

printf("create socket

errorhttp://www.ajxtrc.com/http://www.kmgdlt.com!\n");

exit(1);

}

bzero( &servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons( SERVER_PORT);

servaddr.sin_addr.s_addr = htons( INADDR_ANY);

setnonblock( servfd);

int epfd, nfds;

struct epoll_event ev, events;

epfd = epoll_create( EPOLL_SIZE);

ev.data.fd = servfd;

ev.events = EPOLLIN | EPOLLET ;//| EPOLLHUP | EPOLLERR |

EPOLLRDHUP;

epoll_ctl( epfd, EPOLL_CTL_ADD, servfd, &ev);

if ( bind( servfd, (struct sockaddr*)&servaddr,

sizeof(servaddr)) < 0)

{

printf ("bind to port %d

failure!\n", SERVER_PORT);

exit(1);

}

if( listen(servfd, 10) < 0)

{

printf("call listen

failure!\n");

exit(1);

}

while(1)

{

int i;

nfds = epoll_wait( epfd, events, EPOLLEVENTS_MAXSIZE, 500);

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候......

评论加载中,请稍候...

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值