- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个非常基本的多线程 TCP 客户端服务器系统,并设法使主要功能正常工作,并解决了除一个之外的所有内存问题。
当服务器关闭时,我将其设置为接收和处理 SIGINT 信号,该信号将关闭监听和 connfd 以及执行一些任意输出。
问题是 valgrind 在退出时报告内存泄漏,它说这是来自 pthread_create 并且线程在退出时保持事件状态。对于当时每个连接的用户来说,泄漏的大小为 272 字节。
sig 处理程序和 main 的代码如下:
struct timeval t1, t2;
int connfd = 0;
int listenfd = 0;
pthread_t sniffer_thread;
static void SIGhandler(int sig, siginfo_t *siginfo, void *context)
{
pthread_join(sniffer_thread, NULL);
shutdown(connfd, SHUT_RDWR);
shutdown(listenfd, SHUT_RDWR);
gettimeofday(&t2, NULL);
double totalSeconds = (double) (t2.tv_usec - t1.tv_usec) / 1000000 + (double) (t2.tv_sec - t1.tv_sec) ;
int seconds = ((int)totalSeconds % 60);
int minutes = ((int)totalSeconds % 3600) / 60;
int hours = ((int)totalSeconds % 86400) / 3600;
int days = ((int)totalSeconds % (86400 * 30)) / 86400;
printf("\n\nServer shutdown request received");
printf ("\nTotal server up time = %d days %d hours %d minutes and %d seconds\n\n",days, hours ,minutes , seconds);
close(connfd);
close(listenfd);
exit(EXIT_SUCCESS);
}
int main(void)
{
gettimeofday(&t1, NULL);
struct sigaction act;
memset(&act, '\0', sizeof(act));
// this is a pointer to a function
act.sa_sigaction = &SIGhandler;
// the SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &act, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
struct sockaddr_in serv_addr;
struct sockaddr_in client_addr;
socklen_t socksize = sizeof(struct sockaddr_in);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(50001);
bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (listen(listenfd, 10) == -1) {
perror("Failed to listen");
exit(EXIT_FAILURE);
}
// end socket setup
//Accept and incoming connection
puts("Waiting for incoming connections...");
while (1) {
printf("Waiting for a client to connect...\n\n");
connfd =
accept(listenfd, (struct sockaddr *) &client_addr, &socksize);
printf("\n\nConnection established with: %s\n", inet_ntoa(client_addr.sin_addr));
printf("%s is connected on socket: %d\n",inet_ntoa(client_addr.sin_addr),connfd);
// third parameter is a pointer to the thread function, fourth is its actual parameter
if (pthread_create
(&sniffer_thread, NULL, client_handler,
(void *) &connfd) < 0) {
perror("could not create thread");
exit(EXIT_FAILURE);
}
printf("Handler assigned\n\n");
}
// never reached...
exit(EXIT_SUCCESS);
} // end main()
客户端处理程序代码是:
// thread function - one instance of each for each connected client
void *client_handler(void *socket_desc)
{
pthread_detach(pthread_self());
//Get the socket descriptor
int connfd = *(int *) socket_desc;
send_conConfirm(connfd);
char choice[8];
do {
get_menu_choice(connfd,choice);
switch (*choice) {
case '1':
printf("Executing IP/ID return for socket: %d\n",connfd);
send_studentID(connfd);
break;
case '2':
printf("Executing server time return for socket: %d\n",connfd);
send_serverTime(connfd);
break;
case '3':
printf("Executing sys info return for socket: %d\n",connfd);
send_uname(connfd);
break;
case '4':
printf("Executing file list return for socket: %d\n",connfd);
send_filenames(connfd,choice);
break;
case '5':
send_filenames(connfd,choice);
break;
case '6':
printf("Disconection choice on socket: %d\n",connfd);
break;
default:
printf("Client on socket %d has been disconnected\n", connfd);
goto jump;
break;
}
} while (*choice != '6' );
jump: //jump for goto statement
shutdown(connfd, SHUT_RDWR);
close(connfd);
printf("Thread %lu exiting\n", (unsigned long) pthread_self());
return 0;
} // end client_handler()
我尝试了许多不同的方法,包括在完成后分离线程,但总是以内存泄漏告终。有时,即使客户端仅连接并且服务器结束,也会发生内存泄漏,而其他时候,仅当客户端连接并与服务器交互时才会发生内存泄漏。
最佳答案
您需要在 while 循环结束之前放置一个连接,而不是在信号捕获函数中
我建议您仔细阅读本指南的最后几节,他们处理的代码的一些问题是:
http://www.binarytides.com/socket-programming-c-linux-tutorial/
关于c - pthread_create 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47666459/
我正在努力实现以下目标: 强制新创建的线程在 pthread_create() 之后立即开始运行。没有使用实时调度。 来自pthread_create() man page : Unless real
我想做这样的事情: void *do_work_son(void *data) { mystruct *d = (mystruct*)data; while(tr
typedef struct client { pthread thread; Window_t *win }client; client * client_create(int ID)
我编译最新的 buildroot,并使用输出主机 mipsel-linux-gcc 来编译我的 c 程序。我已经测试了 hello world 程序,它在 MIPS 机器上运行良好(实际上是一个用 p
每当我在我的程序上运行 valgrind 时,它都会告诉我在调用 pthread_create 的任何地方都可能丢失了内存。我一直在尝试遵循 上的指导 valgrind memory leak err
是否有(在 glibc-2.5 和更新版本中)为 pthread_create 定义 Hook 的方法? 有很多二进制应用程序,我想编写一个动态库以通过 LD_PRELOAD 加载 我可以在 main
我正在开发一个多线程程序,但是由于某种原因,我无法创建线程。当我尝试调试时,它在我的pthread_join语句处中断。 for (i = 0; i < numThreads; ++i) { pt
我使用pthread_create()创建了一个线程。新线程创建成功,控制权传递给新创建的线程。然而,主线程似乎不再执行了。主线程处于无限循环中并且永远不会退出。以下是代码片段: void *star
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Multiple arguments to function called by pthread_creat
我在 GCC 中运行我的程序时遇到了段错误。这是一个相当长的程序,所以我只发布我认为相关的部分;如果需要更多信息,请告诉我。 void *RelaxThread(void *para) { p
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
所以我之前就一个具体问题提出了一个问题。我已经查看了该网站上的其他问题,但大多数问题都没有解决我的问题,特别是尽管我认为这个问题对其他初学者很有用。这是代码。 (pi.h) 我的结构是如何布局的 #i
我是 C 新手,这些指针的概念对我来说非常困惑。我试图做一些看起来很简单的事情,但我遇到了很多编译错误。 我想生成一个新线程并将多个指针作为参数传递给它(似乎在 c 中使用全局变量的唯一方法是通过指针
我一生都无法弄清楚为什么这是段错误。 这是段错误 get_ranks_parallel 上线 for (struct node* node = data->plist->head; node!=NUL
我的服务器正在向客户端发送 udp 数据报,并在数据包丢失时从客户端接收 NACK 数据报。我想创建一个线程来处理每个 NACK 数据包,但只有当我有东西要从客户端接收时我才想创建线程。为此,我想使用
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我看过pthread_create的文档 在底部的示例中,他们使用的是: pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &t
我需要将多个参数传递给我想在单独线程上调用的函数。我有read执行此操作的典型方法是定义一个结构体,向函数传递一个指向该结构体的指针,并为参数取消引用它。但是,我无法让它工作: #include #
所以我试图编写一个程序,在c中创建一个线程,其工作是找到2个给定数字中的最大值。我编写的第一个程序(名为askisi.c)如下: #include #include #include int m
程序中存在两个问题首先,当我在主函数中取消注释 pthread_join() 时,会出现段错误,否则程序将运行...其次,输出文件将丢失上次读取文件中存储在全局变量words中的每个单词的第一个字母。
我是一名优秀的程序员,十分优秀!