1. 对sleep()usleep()进行测试

思路:正常来讲,系统调用的休眠函数会将整个线程挂起。而此时我们已经把休眠函数HOOK为我们自己实现的针对协程的的休眠,只会将协程挂起,而不会将线程也挂起。

内容:构建一个IO调度器IOManager放入两个协程去运行,一个协程运行3s,另一个协程运行2s。如果在3s内两个协程都能运行完毕,说明休眠函数HOOK成功。否则,线程级别休眠,应该是5s才能运行完毕。

  • 核心逻辑:

HOOK开发测试 - 图1

  • 代码逻辑:

HOOK开发测试 - 图2

  • 不开启HOOK情况下

整体执行时间为5s,即保留了线程的切换时间。主线程运行第一个任务花费2s,运行第二个任务花费3s。是以阻塞的形式完成运行的。

  1. static Logger::ptr g_logger = KIT_LOG_ROOT();
  2. int main()
  3. {
  4. KIT_LOG_DEBUG(g_logger) << "test begin";
  5. IOManager iom("test", 1);
  6. auto f1 = [](){
  7. KIT_LOG_DEBUG(g_logger) << "f1 start";
  8. sleep(2);
  9. KIT_LOG_DEBUG(g_logger) << "f1 end";
  10. };
  11. auto f2 = [](){
  12. KIT_LOG_DEBUG(g_logger) << "f2 start";
  13. sleep(3);
  14. KIT_LOG_DEBUG(g_logger) << "f2 end";
  15. };
  16. //SetHookEnable(true);
  17. iom.schedule(f1);
  18. iom.schedule(f2);
  19. KIT_LOG_DEBUG(g_logger) << "test end";
  20. return 0;
  21. }

image.png

  • 开启HOOK情况:

3s内两个协程执行完毕,说明HOOK成功,是将协程挂起而线程没有发生休眠。

  1. static Logger::ptr g_logger = KIT_LOG_ROOT();
  2. int main()
  3. {
  4. KIT_LOG_DEBUG(g_logger) << "test begin";
  5. IOManager iom("test", 1);
  6. auto f1 = [](){
  7. KIT_LOG_DEBUG(g_logger) << "f1 start";
  8. sleep(2);
  9. KIT_LOG_DEBUG(g_logger) << "f1 end";
  10. };
  11. auto f2 = [](){
  12. KIT_LOG_DEBUG(g_logger) << "f2 start";
  13. sleep(3);
  14. KIT_LOG_DEBUG(g_logger) << "f2 end";
  15. };
  16. //开启HOOK
  17. SetHookEnable(true);
  18. iom.schedule(f1);
  19. iom.schedule(f2);
  20. KIT_LOG_DEBUG(g_logger) << "test end";
  21. return 0;
  22. }

image.png

2. 对 socket API 进行测试

思路:构建一个简单的客户端,使用socket连接百度的HTTP服务器,观察HOOK 情况

  1. static Logger::ptr g_logger = KIT_LOG_ROOT();
  2. #define PORT 80
  3. #define ADDR "183.232.231.172" //百度服务器
  4. void test_sock()
  5. {
  6. int fd = socket(AF_INET, SOCK_STREAM, 0);
  7. if(fd < 0)
  8. {
  9. KIT_LOG_ERROR(g_logger) << "socket error";
  10. return;
  11. }
  12. struct sockaddr_in sockaddr;
  13. bzero(&sockaddr, sizeof(struct sockaddr_in));
  14. sockaddr.sin_family = AF_INET;
  15. sockaddr.sin_port = htons(PORT);
  16. sockaddr.sin_addr.s_addr = inet_addr(ADDR);
  17. int ret = connect(fd, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr));
  18. if(ret < 0)
  19. {
  20. KIT_LOG_ERROR(g_logger) << "connect error";
  21. return;
  22. }
  23. KIT_LOG_DEBUG(g_logger) << "connect ret = " << ret << ", errno = " << errno << ", is" << strerror(errno);
  24. std::stringstream p;
  25. p << "GET / HTTP/1.0\r\n\r\n";
  26. ret = write(fd, (void *)p.str().c_str(), p.str().size());
  27. std::string msg;
  28. msg.resize(1024*1024);
  29. ret = read(fd, &msg[0], msg.size());
  30. KIT_LOG_DEBUG(g_logger) << "recv msg: " << msg;
  31. }
  32. int main()
  33. {
  34. KIT_LOG_DEBUG(g_logger) << "test begin";
  35. IOManager iom("test_sock", 1);
  36. iom.schedule(&test_sock);
  37. KIT_LOG_DEBUG(g_logger) << "test end";
  38. return 0;
  39. }

image.png