void JudegAlert(void *)
{
....
sleep(50);
}
int main()
{
......
pthread_create(&pthrd, NULL, JudegAlert, NULL);//这里创建一个线程
.....
while(1)
{
epoll_wait (kdpfd, events, curfds, 100);
.....
accept (listener, (struct sockaddr *) &their_addr, &len);
//下面就是解析数据了
.....
}
}
本来我的意思是:创建一个线程,线程是每隔50秒就检查一遍数据库等,然后主程序一直是等待数据读取过来,
现在我发现,主程序也在sleep,不知道为啥? 当时测试的时候是这样的,就是有一个客户端是每隔50秒给我发送一次数据,数据中有2个包,
然后我看了下我的程序,我好像在我只能一次接收2个包,如果还有的话就又要等50秒了,一次只能是2个包??? 还要等50秒,这是为啥呢???
28 个解决方案
#1
你的接收,是不是阻塞式的
#2
问题应该出在epoll_wait上
你看看你的线程中sleep的时候有没有释放 events
你看看你的线程中sleep的时候有没有释放 events
#3
linux 的sleep是进程沉睡
#4
用这个吧,我多年前写的,可以线程沉睡,编译开关lz能明白吧,你可以自己去掉
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
Sleep(sleepSecond);
#endif
return;
}
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
Sleep(sleepSecond);
#endif
return;
}
#5
我的函数参数单位是毫秒(1/1000)秒,不是秒,lz注意,另外,linux下sleep的参数单位也是毫秒
#6
我设置epool_wait如下:
nfds = epoll_wait (kdpfd, events, curfds, 100);
设置的时候是100毫秒,应该是非阻塞吧
还有 “nfer_cn” 你说“sleep的时候有没有释放 events” 这个什么意思?
还要释放那个么?
nfds = epoll_wait (kdpfd, events, curfds, 100);
设置的时候是100毫秒,应该是非阻塞吧
还有 “nfer_cn” 你说“sleep的时候有没有释放 events” 这个什么意思?
还要释放那个么?
#7
你好 “ Meteor_Code ”,我用了你的那个thread_sleep 好像还是不行,还 是会出现上述情况
只能一次接收2个包,如果还有的话就又要等50秒了,一次只能是2个包???
主程序代码如下:
int main (int argc, char **argv)
{
int listener, new_fd, kdpfd, nfds, n, ret, curfds, rets;
int res = 0;
int on = 1;
int err;
int Flag_Judeg = 0;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
unsigned int myport, lisnum;
struct epoll_event ev;
struct epoll_event events[MAX_EPOLL_SIZE];
struct rlimit rt;
myport = 8900;
lisnum = 2;
int i;
pthread_t pthrd;
if (getrlimit (RLIMIT_NOFILE, &rt) == -1)
{
perror ("Get the system rlimit fail");
exit (1);
}
else
{
//获取系统参数资源成功
printf ("Get the system parameters resources success,maxnum=%d\n",rt.rlim_max);
}
// 开启 socket 监听
if ((listener = socket (PF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
else
{ //创建成功!
printf ("socket Create success!\n");
}
setnonblocking (listener);
//使用 SO_REUSEADDR 套接字选项避免地址使用错误,为了允许地址重用,设置整型参数(on)为 1 (不然,可以设为 0 来禁止地址重用)。
rets = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
bzero (&my_addr, sizeof (my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons (myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind (listener, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) == -1)
{
perror ("bind");
exit (1);
}
else
{ //地址和端口绑定成功
printf ("IP Address and port binding success, port=%d\n", myport);
//printf("IP Address and port binding success, Ip=%s,port=%d\n",my_addr.sin_addr.s_addr,myport);
}
if (listen (listener, lisnum) == -1)
{
perror ("listen");
exit (1);
}
else
{ //开启服务成功!
printf ("Open service success!\n");
}
//创建 epoll 句柄,把监听 socket 加入到 epoll 集合里
kdpfd = epoll_create (MAX_EPOLL_SIZE);
len = sizeof (struct sockaddr_in);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
{
fprintf (stderr, "epoll set insertion error: fd=%d\n", listener);
return -1;
}
else
{ //监听 socket 加入 epoll 成功!
printf ("Listening socket to join epoll success!\n");
}
curfds = 1;
//DBPROCESS *dbprocess = NULL;
dbprocess = g_Readorwrite.ConnectToDb ();
//dbprocess = NULL;
while(1)
{
err = pthread_create(&pthrd, NULL, JudegSourceToAlert, NULL);
if(err != 0)
{
printf("can't create thread: %s\n",strerror(err));
//return 1;
continue ;
}
else
{
printf("pthread_create for JudegSourceToAlert Success!\n");
break;
}
}
while (1)
{
//等待有事件发生
nfds = epoll_wait (kdpfd, events, curfds, 100);
if (nfds == -1)
{
printf ("errno=%d,%s\r\n", errno, strerror (errno));
if (errno == EINTR)
{
continue;
}
else
{
perror ("epoll_wait");
break;
}
}
if (dbprocess == NULL)
{
//printf("Conncet To DB!\n");
dbprocess = g_Readorwrite.ConnectToDb ();
}
if (dbprocess != NULL)
{
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listener)
{
new_fd = accept (listener, (struct sockaddr *) &their_addr, &len);
if (new_fd < 0)
{
perror ("accept");
continue;
}
else
{
//有连接来自于: %d:%d, 分配的 socket 为:%d
printf("There is a connection from %d:%d, distribution of socket is:%d\n", inet_ntoa (their_addr.sin_addr), ntohs (their_addr.sin_port), new_fd);
}
setnonblocking (new_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = new_fd;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0)
{ //把 socket '%d' 加入 epoll 失败!
fprintf (stderr,"socket '%d' join to epoll failure %s\n", new_fd, strerror (errno));
return -1;
}
curfds++;
}
else
{
ret = recv_message (dbprocess, events[n].data.fd);
if (ret < 1 && errno != 11)
{
printf ("socket is colse : %d %d %d\n", events[n].data.fd, ret, errno);
epoll_ctl (kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev);
curfds--;
//dbprocess = NULL;
}
}
}
}
}
if(pthrd !=0)
{ //等待线程结束
pthread_join(pthrd,NULL);
printf("Thread [JudegSourceToAlert] is over \n");
}
close (listener);
return 0;
}
下面就是线程
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
sleep(sleepSecond/1000);
#endif
return;
}
void *JudegSourceToAlert (void *)
{
while(1)
{
JudegToAlert ();
//sleep(g_Readorwrite.m_settime);
thread_sleep(g_Readorwrite.m_settime*1000);
}
// pthread_exit(NULL);
}
那我上面有问题么?
只能一次接收2个包,如果还有的话就又要等50秒了,一次只能是2个包???
主程序代码如下:
int main (int argc, char **argv)
{
int listener, new_fd, kdpfd, nfds, n, ret, curfds, rets;
int res = 0;
int on = 1;
int err;
int Flag_Judeg = 0;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
unsigned int myport, lisnum;
struct epoll_event ev;
struct epoll_event events[MAX_EPOLL_SIZE];
struct rlimit rt;
myport = 8900;
lisnum = 2;
int i;
pthread_t pthrd;
if (getrlimit (RLIMIT_NOFILE, &rt) == -1)
{
perror ("Get the system rlimit fail");
exit (1);
}
else
{
//获取系统参数资源成功
printf ("Get the system parameters resources success,maxnum=%d\n",rt.rlim_max);
}
// 开启 socket 监听
if ((listener = socket (PF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
else
{ //创建成功!
printf ("socket Create success!\n");
}
setnonblocking (listener);
//使用 SO_REUSEADDR 套接字选项避免地址使用错误,为了允许地址重用,设置整型参数(on)为 1 (不然,可以设为 0 来禁止地址重用)。
rets = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
bzero (&my_addr, sizeof (my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons (myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind (listener, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) == -1)
{
perror ("bind");
exit (1);
}
else
{ //地址和端口绑定成功
printf ("IP Address and port binding success, port=%d\n", myport);
//printf("IP Address and port binding success, Ip=%s,port=%d\n",my_addr.sin_addr.s_addr,myport);
}
if (listen (listener, lisnum) == -1)
{
perror ("listen");
exit (1);
}
else
{ //开启服务成功!
printf ("Open service success!\n");
}
//创建 epoll 句柄,把监听 socket 加入到 epoll 集合里
kdpfd = epoll_create (MAX_EPOLL_SIZE);
len = sizeof (struct sockaddr_in);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
{
fprintf (stderr, "epoll set insertion error: fd=%d\n", listener);
return -1;
}
else
{ //监听 socket 加入 epoll 成功!
printf ("Listening socket to join epoll success!\n");
}
curfds = 1;
//DBPROCESS *dbprocess = NULL;
dbprocess = g_Readorwrite.ConnectToDb ();
//dbprocess = NULL;
while(1)
{
err = pthread_create(&pthrd, NULL, JudegSourceToAlert, NULL);
if(err != 0)
{
printf("can't create thread: %s\n",strerror(err));
//return 1;
continue ;
}
else
{
printf("pthread_create for JudegSourceToAlert Success!\n");
break;
}
}
while (1)
{
//等待有事件发生
nfds = epoll_wait (kdpfd, events, curfds, 100);
if (nfds == -1)
{
printf ("errno=%d,%s\r\n", errno, strerror (errno));
if (errno == EINTR)
{
continue;
}
else
{
perror ("epoll_wait");
break;
}
}
if (dbprocess == NULL)
{
//printf("Conncet To DB!\n");
dbprocess = g_Readorwrite.ConnectToDb ();
}
if (dbprocess != NULL)
{
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listener)
{
new_fd = accept (listener, (struct sockaddr *) &their_addr, &len);
if (new_fd < 0)
{
perror ("accept");
continue;
}
else
{
//有连接来自于: %d:%d, 分配的 socket 为:%d
printf("There is a connection from %d:%d, distribution of socket is:%d\n", inet_ntoa (their_addr.sin_addr), ntohs (their_addr.sin_port), new_fd);
}
setnonblocking (new_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = new_fd;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0)
{ //把 socket '%d' 加入 epoll 失败!
fprintf (stderr,"socket '%d' join to epoll failure %s\n", new_fd, strerror (errno));
return -1;
}
curfds++;
}
else
{
ret = recv_message (dbprocess, events[n].data.fd);
if (ret < 1 && errno != 11)
{
printf ("socket is colse : %d %d %d\n", events[n].data.fd, ret, errno);
epoll_ctl (kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev);
curfds--;
//dbprocess = NULL;
}
}
}
}
}
if(pthrd !=0)
{ //等待线程结束
pthread_join(pthrd,NULL);
printf("Thread [JudegSourceToAlert] is over \n");
}
close (listener);
return 0;
}
下面就是线程
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
sleep(sleepSecond/1000);
#endif
return;
}
void *JudegSourceToAlert (void *)
{
while(1)
{
JudegToAlert ();
//sleep(g_Readorwrite.m_settime);
thread_sleep(g_Readorwrite.m_settime*1000);
}
// pthread_exit(NULL);
}
那我上面有问题么?
#8
.........
void thread_sleep(unsigned long sleepSecond)
{
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
return;
}
请把编译开关去掉...........................
void thread_sleep(unsigned long sleepSecond)
{
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
return;
}
请把编译开关去掉...........................
#9
我的代码是为了跨平台
你的环境中没有APP_USE_SYS == APP_SYS_LINUX宏
那不又是使用sleep了吗!....
汗流不止....
你的环境中没有APP_USE_SYS == APP_SYS_LINUX宏
那不又是使用sleep了吗!....
汗流不止....
#10
#include "stdlib.h"
#include "string.h"
#include "netdb.h"
#include "fcntl.h"
#include "unistd.h"
#include "pthread.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "sys/socket.h"
头文件
...........................
人生最痛苦的事情:有代码,却不能正确使用........
#include "string.h"
#include "netdb.h"
#include "fcntl.h"
#include "unistd.h"
#include "pthread.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "sys/socket.h"
头文件
...........................
人生最痛苦的事情:有代码,却不能正确使用........
#11
while(结束条件)
{
....
Sleep();
}
{
....
Sleep();
}
#12
你好:“ Meteor_Code ” ,呵呵 ,刚才不好意思了,
但是我运行了程序,发现有时候会立马就会接收到客户端发过来的数据,但是有时候还是要等待呢,这个不知道咋回事呢???
但是我运行了程序,发现有时候会立马就会接收到客户端发过来的数据,但是有时候还是要等待呢,这个不知道咋回事呢???
#13
还有,那个
我在调用thread_sleep(g_Readorwrite.m_settime*1000);我乘以了1000,
g_Readorwrite.m_settime = 50(秒)
然后放到那个函数里调用呢 这样么
我在调用thread_sleep(g_Readorwrite.m_settime*1000);我乘以了1000,
g_Readorwrite.m_settime = 50(秒)
然后放到那个函数里调用呢 这样么
#14
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
#15
顶一个。
#16
这个说法完全错误,在一个线程中睡眠,不会影响另外一个线程。
#17
自己看sleep的文档说明,自己测试,不要和我说一个线程阻塞会不会引起其他线程的阻塞
现在我说的是sleep的功能就是整个进程沉睡
#18
学习。
#19
你使用的epoll边缘触发模式,另外你是非阻塞,你查查recv_message,是不是把数据读完了
另外Meteor_Code说的情况,我觉得你这里不是那种情况
另外Meteor_Code说的情况,我觉得你这里不是那种情况
#20
虽然man手册上面写着“sleep() makes the calling process sleep until seconds seconds have elapsed or a signal arrives which is not ignored.” 但是实际上,sleep只会阻塞当前线程,不会对其他线程造成任何影响。你竟然还懂得测试这个道理,那为什么不自己去测试?我已经做了上百次的测试了。
#21
这个说法也是错误的,sleep的参数单位是秒,你是用哪个山寨版本的linux的?
#22
的确清楚
process:意思就是进程
thread:才是线程
fedora8下测试过很多次,sleep的确造成了整个进程的阻塞
lz的例子也很明确证明了这一点
另外,的确,linux下sleep的单位参数是秒,这个我不否定
#23
呵呵,想起了我以前,
LZ,我的linux下的sleep是秒,不是毫秒···
LZ,我的linux下的sleep是秒,不是毫秒···
#24
是epoll 出问题了, LT or GT
不是sleep 问题
接分小王
不是sleep 问题
接分小王
#25
如果线程的阻塞会互相影响的话,那线程的存在就没有任何意义了,线程本来就是为并发执行创造的。只有信号处理函数会阻塞所有的线程。在Linux内核的进程调度中,调度的对象是线程,换句话说,每个线程其实都是作为一个进程在运行的。
关于POSIX线程的更多信息,你可以参考以下地址:
https://computing.llnl.gov/tutorials/pthreads/#Thread
#26
可以肯定与void JudegAlert(void *)
的延时无关
的延时无关
#27
唉, 还是没有解决,有时会快,有时会慢,待处理中。。。
#28
同意这种办法。
#1
你的接收,是不是阻塞式的
#2
问题应该出在epoll_wait上
你看看你的线程中sleep的时候有没有释放 events
你看看你的线程中sleep的时候有没有释放 events
#3
linux 的sleep是进程沉睡
#4
用这个吧,我多年前写的,可以线程沉睡,编译开关lz能明白吧,你可以自己去掉
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
Sleep(sleepSecond);
#endif
return;
}
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
Sleep(sleepSecond);
#endif
return;
}
#5
我的函数参数单位是毫秒(1/1000)秒,不是秒,lz注意,另外,linux下sleep的参数单位也是毫秒
#6
我设置epool_wait如下:
nfds = epoll_wait (kdpfd, events, curfds, 100);
设置的时候是100毫秒,应该是非阻塞吧
还有 “nfer_cn” 你说“sleep的时候有没有释放 events” 这个什么意思?
还要释放那个么?
nfds = epoll_wait (kdpfd, events, curfds, 100);
设置的时候是100毫秒,应该是非阻塞吧
还有 “nfer_cn” 你说“sleep的时候有没有释放 events” 这个什么意思?
还要释放那个么?
#7
你好 “ Meteor_Code ”,我用了你的那个thread_sleep 好像还是不行,还 是会出现上述情况
只能一次接收2个包,如果还有的话就又要等50秒了,一次只能是2个包???
主程序代码如下:
int main (int argc, char **argv)
{
int listener, new_fd, kdpfd, nfds, n, ret, curfds, rets;
int res = 0;
int on = 1;
int err;
int Flag_Judeg = 0;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
unsigned int myport, lisnum;
struct epoll_event ev;
struct epoll_event events[MAX_EPOLL_SIZE];
struct rlimit rt;
myport = 8900;
lisnum = 2;
int i;
pthread_t pthrd;
if (getrlimit (RLIMIT_NOFILE, &rt) == -1)
{
perror ("Get the system rlimit fail");
exit (1);
}
else
{
//获取系统参数资源成功
printf ("Get the system parameters resources success,maxnum=%d\n",rt.rlim_max);
}
// 开启 socket 监听
if ((listener = socket (PF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
else
{ //创建成功!
printf ("socket Create success!\n");
}
setnonblocking (listener);
//使用 SO_REUSEADDR 套接字选项避免地址使用错误,为了允许地址重用,设置整型参数(on)为 1 (不然,可以设为 0 来禁止地址重用)。
rets = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
bzero (&my_addr, sizeof (my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons (myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind (listener, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) == -1)
{
perror ("bind");
exit (1);
}
else
{ //地址和端口绑定成功
printf ("IP Address and port binding success, port=%d\n", myport);
//printf("IP Address and port binding success, Ip=%s,port=%d\n",my_addr.sin_addr.s_addr,myport);
}
if (listen (listener, lisnum) == -1)
{
perror ("listen");
exit (1);
}
else
{ //开启服务成功!
printf ("Open service success!\n");
}
//创建 epoll 句柄,把监听 socket 加入到 epoll 集合里
kdpfd = epoll_create (MAX_EPOLL_SIZE);
len = sizeof (struct sockaddr_in);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
{
fprintf (stderr, "epoll set insertion error: fd=%d\n", listener);
return -1;
}
else
{ //监听 socket 加入 epoll 成功!
printf ("Listening socket to join epoll success!\n");
}
curfds = 1;
//DBPROCESS *dbprocess = NULL;
dbprocess = g_Readorwrite.ConnectToDb ();
//dbprocess = NULL;
while(1)
{
err = pthread_create(&pthrd, NULL, JudegSourceToAlert, NULL);
if(err != 0)
{
printf("can't create thread: %s\n",strerror(err));
//return 1;
continue ;
}
else
{
printf("pthread_create for JudegSourceToAlert Success!\n");
break;
}
}
while (1)
{
//等待有事件发生
nfds = epoll_wait (kdpfd, events, curfds, 100);
if (nfds == -1)
{
printf ("errno=%d,%s\r\n", errno, strerror (errno));
if (errno == EINTR)
{
continue;
}
else
{
perror ("epoll_wait");
break;
}
}
if (dbprocess == NULL)
{
//printf("Conncet To DB!\n");
dbprocess = g_Readorwrite.ConnectToDb ();
}
if (dbprocess != NULL)
{
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listener)
{
new_fd = accept (listener, (struct sockaddr *) &their_addr, &len);
if (new_fd < 0)
{
perror ("accept");
continue;
}
else
{
//有连接来自于: %d:%d, 分配的 socket 为:%d
printf("There is a connection from %d:%d, distribution of socket is:%d\n", inet_ntoa (their_addr.sin_addr), ntohs (their_addr.sin_port), new_fd);
}
setnonblocking (new_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = new_fd;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0)
{ //把 socket '%d' 加入 epoll 失败!
fprintf (stderr,"socket '%d' join to epoll failure %s\n", new_fd, strerror (errno));
return -1;
}
curfds++;
}
else
{
ret = recv_message (dbprocess, events[n].data.fd);
if (ret < 1 && errno != 11)
{
printf ("socket is colse : %d %d %d\n", events[n].data.fd, ret, errno);
epoll_ctl (kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev);
curfds--;
//dbprocess = NULL;
}
}
}
}
}
if(pthrd !=0)
{ //等待线程结束
pthread_join(pthrd,NULL);
printf("Thread [JudegSourceToAlert] is over \n");
}
close (listener);
return 0;
}
下面就是线程
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
sleep(sleepSecond/1000);
#endif
return;
}
void *JudegSourceToAlert (void *)
{
while(1)
{
JudegToAlert ();
//sleep(g_Readorwrite.m_settime);
thread_sleep(g_Readorwrite.m_settime*1000);
}
// pthread_exit(NULL);
}
那我上面有问题么?
只能一次接收2个包,如果还有的话就又要等50秒了,一次只能是2个包???
主程序代码如下:
int main (int argc, char **argv)
{
int listener, new_fd, kdpfd, nfds, n, ret, curfds, rets;
int res = 0;
int on = 1;
int err;
int Flag_Judeg = 0;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
unsigned int myport, lisnum;
struct epoll_event ev;
struct epoll_event events[MAX_EPOLL_SIZE];
struct rlimit rt;
myport = 8900;
lisnum = 2;
int i;
pthread_t pthrd;
if (getrlimit (RLIMIT_NOFILE, &rt) == -1)
{
perror ("Get the system rlimit fail");
exit (1);
}
else
{
//获取系统参数资源成功
printf ("Get the system parameters resources success,maxnum=%d\n",rt.rlim_max);
}
// 开启 socket 监听
if ((listener = socket (PF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
else
{ //创建成功!
printf ("socket Create success!\n");
}
setnonblocking (listener);
//使用 SO_REUSEADDR 套接字选项避免地址使用错误,为了允许地址重用,设置整型参数(on)为 1 (不然,可以设为 0 来禁止地址重用)。
rets = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
bzero (&my_addr, sizeof (my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons (myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind (listener, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) == -1)
{
perror ("bind");
exit (1);
}
else
{ //地址和端口绑定成功
printf ("IP Address and port binding success, port=%d\n", myport);
//printf("IP Address and port binding success, Ip=%s,port=%d\n",my_addr.sin_addr.s_addr,myport);
}
if (listen (listener, lisnum) == -1)
{
perror ("listen");
exit (1);
}
else
{ //开启服务成功!
printf ("Open service success!\n");
}
//创建 epoll 句柄,把监听 socket 加入到 epoll 集合里
kdpfd = epoll_create (MAX_EPOLL_SIZE);
len = sizeof (struct sockaddr_in);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
{
fprintf (stderr, "epoll set insertion error: fd=%d\n", listener);
return -1;
}
else
{ //监听 socket 加入 epoll 成功!
printf ("Listening socket to join epoll success!\n");
}
curfds = 1;
//DBPROCESS *dbprocess = NULL;
dbprocess = g_Readorwrite.ConnectToDb ();
//dbprocess = NULL;
while(1)
{
err = pthread_create(&pthrd, NULL, JudegSourceToAlert, NULL);
if(err != 0)
{
printf("can't create thread: %s\n",strerror(err));
//return 1;
continue ;
}
else
{
printf("pthread_create for JudegSourceToAlert Success!\n");
break;
}
}
while (1)
{
//等待有事件发生
nfds = epoll_wait (kdpfd, events, curfds, 100);
if (nfds == -1)
{
printf ("errno=%d,%s\r\n", errno, strerror (errno));
if (errno == EINTR)
{
continue;
}
else
{
perror ("epoll_wait");
break;
}
}
if (dbprocess == NULL)
{
//printf("Conncet To DB!\n");
dbprocess = g_Readorwrite.ConnectToDb ();
}
if (dbprocess != NULL)
{
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listener)
{
new_fd = accept (listener, (struct sockaddr *) &their_addr, &len);
if (new_fd < 0)
{
perror ("accept");
continue;
}
else
{
//有连接来自于: %d:%d, 分配的 socket 为:%d
printf("There is a connection from %d:%d, distribution of socket is:%d\n", inet_ntoa (their_addr.sin_addr), ntohs (their_addr.sin_port), new_fd);
}
setnonblocking (new_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = new_fd;
if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0)
{ //把 socket '%d' 加入 epoll 失败!
fprintf (stderr,"socket '%d' join to epoll failure %s\n", new_fd, strerror (errno));
return -1;
}
curfds++;
}
else
{
ret = recv_message (dbprocess, events[n].data.fd);
if (ret < 1 && errno != 11)
{
printf ("socket is colse : %d %d %d\n", events[n].data.fd, ret, errno);
epoll_ctl (kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev);
curfds--;
//dbprocess = NULL;
}
}
}
}
}
if(pthrd !=0)
{ //等待线程结束
pthread_join(pthrd,NULL);
printf("Thread [JudegSourceToAlert] is over \n");
}
close (listener);
return 0;
}
下面就是线程
void thread_sleep(unsigned long sleepSecond)
{
#if (APP_USE_SYS == APP_SYS_LINUX)
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
#else
sleep(sleepSecond/1000);
#endif
return;
}
void *JudegSourceToAlert (void *)
{
while(1)
{
JudegToAlert ();
//sleep(g_Readorwrite.m_settime);
thread_sleep(g_Readorwrite.m_settime*1000);
}
// pthread_exit(NULL);
}
那我上面有问题么?
#8
.........
void thread_sleep(unsigned long sleepSecond)
{
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
return;
}
请把编译开关去掉...........................
void thread_sleep(unsigned long sleepSecond)
{
timeval t_timeval;
t_timeval.tv_sec = (sleepSecond / 1000);
t_timeval.tv_usec = (sleepSecond % 1000);
select(0, NULL, NULL, NULL, &t_timeval);
return;
}
请把编译开关去掉...........................
#9
我的代码是为了跨平台
你的环境中没有APP_USE_SYS == APP_SYS_LINUX宏
那不又是使用sleep了吗!....
汗流不止....
你的环境中没有APP_USE_SYS == APP_SYS_LINUX宏
那不又是使用sleep了吗!....
汗流不止....
#10
#include "stdlib.h"
#include "string.h"
#include "netdb.h"
#include "fcntl.h"
#include "unistd.h"
#include "pthread.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "sys/socket.h"
头文件
...........................
人生最痛苦的事情:有代码,却不能正确使用........
#include "string.h"
#include "netdb.h"
#include "fcntl.h"
#include "unistd.h"
#include "pthread.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "sys/socket.h"
头文件
...........................
人生最痛苦的事情:有代码,却不能正确使用........
#11
while(结束条件)
{
....
Sleep();
}
{
....
Sleep();
}
#12
你好:“ Meteor_Code ” ,呵呵 ,刚才不好意思了,
但是我运行了程序,发现有时候会立马就会接收到客户端发过来的数据,但是有时候还是要等待呢,这个不知道咋回事呢???
但是我运行了程序,发现有时候会立马就会接收到客户端发过来的数据,但是有时候还是要等待呢,这个不知道咋回事呢???
#13
还有,那个
我在调用thread_sleep(g_Readorwrite.m_settime*1000);我乘以了1000,
g_Readorwrite.m_settime = 50(秒)
然后放到那个函数里调用呢 这样么
我在调用thread_sleep(g_Readorwrite.m_settime*1000);我乘以了1000,
g_Readorwrite.m_settime = 50(秒)
然后放到那个函数里调用呢 这样么
#14
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
#15
顶一个。
#16
这个说法完全错误,在一个线程中睡眠,不会影响另外一个线程。
#17
自己看sleep的文档说明,自己测试,不要和我说一个线程阻塞会不会引起其他线程的阻塞
现在我说的是sleep的功能就是整个进程沉睡
#18
学习。
#19
你使用的epoll边缘触发模式,另外你是非阻塞,你查查recv_message,是不是把数据读完了
另外Meteor_Code说的情况,我觉得你这里不是那种情况
另外Meteor_Code说的情况,我觉得你这里不是那种情况
#20
虽然man手册上面写着“sleep() makes the calling process sleep until seconds seconds have elapsed or a signal arrives which is not ignored.” 但是实际上,sleep只会阻塞当前线程,不会对其他线程造成任何影响。你竟然还懂得测试这个道理,那为什么不自己去测试?我已经做了上百次的测试了。
#21
这个说法也是错误的,sleep的参数单位是秒,你是用哪个山寨版本的linux的?
#22
的确清楚
process:意思就是进程
thread:才是线程
fedora8下测试过很多次,sleep的确造成了整个进程的阻塞
lz的例子也很明确证明了这一点
另外,的确,linux下sleep的单位参数是秒,这个我不否定
#23
呵呵,想起了我以前,
LZ,我的linux下的sleep是秒,不是毫秒···
LZ,我的linux下的sleep是秒,不是毫秒···
#24
是epoll 出问题了, LT or GT
不是sleep 问题
接分小王
不是sleep 问题
接分小王
#25
如果线程的阻塞会互相影响的话,那线程的存在就没有任何意义了,线程本来就是为并发执行创造的。只有信号处理函数会阻塞所有的线程。在Linux内核的进程调度中,调度的对象是线程,换句话说,每个线程其实都是作为一个进程在运行的。
关于POSIX线程的更多信息,你可以参考以下地址:
https://computing.llnl.gov/tutorials/pthreads/#Thread
#26
可以肯定与void JudegAlert(void *)
的延时无关
的延时无关
#27
唉, 还是没有解决,有时会快,有时会慢,待处理中。。。
#28
同意这种办法。