LinuxC语⾔socket多线程(循环创建多个线程,同时进⾏,⾮
阻塞)
我看了⼀些博客,多线程⽹络编程⽤的是堵塞,也就是 pthread_join 函数,可是既然是监听接⼝怎么能⽤堵塞的。
我要做的东西是:监听80端⼝,然后接收请求,创建⼀个线程完成相应任务。
我遇到的问题是:⽤阻塞(也就是pthread_join(thread_id))相当于单线程⽆法满⾜要求,⽤⾮阻塞(pthread_detach(thread_id))然后我的socket没反应。
问题原因:在⼀个循环中创建的Socket,如果socket的id是局部变量那么当前循环结束后,该变量的空间就会被回收掉,导致进⼊线程函数之后,获取不到socket的id的值。
解决⽅法:⽤malloc申请⼀个int的空间存储socket的id,然后在线程中释放这⽚空间。
接下来放错误代码和成功代码:
错误代码1:(不算错误,只是⽤了阻塞,创建的线程未执⾏完之前不会创建其他线程)
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int tSock = 0;//注意三个程序中这⾥的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求
if(tSock<0)
{
close(tSock);
continue;
}
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)&tSock);//创建线程
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
pthread_join(id,NULL);//线程是阻塞的
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
错误代码2:(虽然是⾮阻塞的,但是socket的id进⼊线程后空间马上就被回收了)
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int tSock = 0;//注意三个程序中这⾥的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求
if(tSock<0)
{
close(tSock);
continue;
}
connect和join的区别
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)&tSock);//创建线程 pthread_detach(id);//线程⾮阻塞
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
正确的多线程:
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int* tSock = (int *)malloc(sizeof(int));//注意三个程序中这⾥的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
*tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求 if(*tSock<0)
{
close(*tSock);
continue;
}
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)tSock);//创建线程 pthread_detach(id);//线程⾮阻塞
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
free(tSock);//在这⾥释放空间
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
记录:记得给socket的id分配空间,⽤完之后记得free掉
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论