多线程中的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);
分享:
喜欢
0
赠金笔
加载中,请稍候......
评论加载中,请稍候...
发评论
登录名: 密码: 找回密码 注册记住登录状态
昵 称:
评论并转载此博文
发评论
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。