我无法弄清楚代码的奇怪行为。 程序基本上会监听tcp端口,在获取启动/停止命令后,它会创建一个curl线程并开始下载流。 问题是,每次下载流时,程序都会在共享内存中增长。经过多次下载后,程序停止工作。 - 它接受启动/停止命令,但只下载一小块数据。我假设,有一些内存泄漏。 代码:
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <curl/curl.h>
#define MY_PORT 8888
#define MAXBUF 1024
int hour=1,min=1,sec=1,year=0,month=0,mday=0;
int stop=0;
static void daemon();
CURL *curl;
CURLcode res;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
if(stop)
return -1;
return written;
}
void * curl_thread(){
FILE *fp;
char format[] = "/root/test/archive_%d-%s-%s_%s.%s.%s.mp3";
char outfilename[sizeof format+100];
char mi[3];
char mth[3];
char dom[3];
char hrs[3];
char secs[3];
sprintf(mth, "%d", month);
sprintf(dom, "%d", mday);
sprintf(hrs, "%d", hour);
sprintf(mi, "%d", min);
sprintf(secs, "%d", sec);
if (month<10){
sprintf(mth, "0%d", month);}
if (mday<10){
sprintf(dom, "0%d", mday); }
if (hour<10){
sprintf(hrs, "0%d", hour); }
if (min<10){
sprintf(mi, "0%d", min);}
if (sec<10){
sprintf(secs, "0%d", sec);}
sprintf(outfilename,format,year,mth,dom,hrs,mi,secs);
curl = curl_easy_init();
if(curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8000/stream.mp3");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl capture");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
stop=0;
pthread_exit(0);
}
void time_date(void){
time_t rawtime;
time (&rawtime);
struct tm *tm_struct = localtime(&rawtime);
hour = tm_struct->tm_hour;
min = tm_struct->tm_min;
sec= tm_struct->tm_sec;
year=tm_struct->tm_year + 1900;
month=tm_struct->tm_mon + 1;
mday=tm_struct->tm_mday;
}
void daemon(){
pid_t mypid;
FILE *pid;
mypid=fork();
if (mypid){
pid=fopen("acapt.pid","w");
fprintf(pid,"%i",mypid);
exit (0);
}
}
int main(int Count, char *Strings[])
{
daemon();
time_date();
int thread=0;
int sockfd;
struct sockaddr_in self;
char buffer[MAXBUF];
char buff[MAXBUF];
//---Create streaming socket---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
perror("Socket");
exit(errno);
}
///Initialize address/port structure---*/
bzero(&self, sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;//*---Assign a port number to the socket---*/
if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
{
perror("socket--bind");
exit(errno);
}
///*---Make it a "listening socket"---*/
if ( listen(sockfd, 20) != 0 )
{
perror("socket--listen");
exit(errno);
}
//*---Forever... ---*/
while (1)
{ int clientfd;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
//*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr,&addrlen);
//*---Echo back anything sent---*/
recv(clientfd, buffer, MAXBUF, 0);
if (strcmp(buffer, "start\r\n")==0&&!thread){
close(clientfd);
sleep(5);
time_date();
pthread_t tid;
pthread_create(&tid,NULL,curl_thread,NULL);
thread=1;
}
if (strcmp(buffer, "stop\r\n")==0&&thread){
close(clientfd);
stop=1;
thread=0;
curl_global_cleanup();
}
memset ( buffer, '\0', MAXBUF );
//*---Close data connection---*/
close(clientfd);
}
//---Clean up (should never get here!)---*/
close(sockfd);
return 0;
}
一次开始/停止后来自valgrind的信息:
HEAP SUMMARY:
in use at exit: 4,897 bytes in 58 blocks total heap usage: 2,987 allocs, 2,929 frees, 200,756 bytes allocated 576 bytes in 2 blocks are possibly lost in loss record 16 of 20
at 0x4C272B8: calloc (vg_replace_malloc.c:566)
by 0x401128E: _dl_allocate_tls (dl-tls.c:300)
by 0x4E36483: pthread_create@@GLIBC_2.2.5 (allocatestack.c:580)
by 0x4016A2: main (in /root/test/testas) LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 576 bytes in 2 blocks
still reachable: 4,321 bytes in 56 blocks
suppressed: 0 bytes in 0 blocks
Reachable blocks (those to which a pointer was found) are not shown.
To see them, rerun with: --leak-check=full --show-reachable=yes
For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 6)
谢谢你的帮助。
答案 0 :(得分:0)
这可能不会导致崩溃,但是您没有将正确的函数类型传递给pthread_create()。它应该是:
void * curl_thread( void* data )
{
...
您也永远不会加入线程,每次创建新资源时都会泄漏资源。调用pthread_join()或pthread_detach()。