英文:
argument provided to the thread function prints garbage in pthread
问题
我正在尝试打印作为pthread_create()函数中的最后一个参数提供给线程函数"monitor_loglevel_change_handler"的参数的值,但它打印出垃圾而不是正确的值。然而,在代码的前面部分,它已经正确提供并打印了,详见注释
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/inotify.h>
#include <errno.h>
#include <sys/stat.h>
char *read_env_param(const char* envkey)
{
if(envkey)
{
char *value = getenv(envkey);
if(value)
return strdup(value);
}
return NULL;
}
static void *monitor_loglevel_change_handler(void* arg)
{
char *fileName = (char*) arg;
int ifd; // the inotify file des
int wfd; // the watched file des
ssize_t n = 0;
char* dname=NULL; // directory name
char* bname = NULL; // basename
char* tok=NULL;
printf("参数的值:%s\n", (char*) arg); // --------> 为什么什么都不打印??
dname = strdup( fileName); // 解析文件名为目录名和基本文件名
if( (tok = strrchr( dname, '/')) != NULL ) {
*tok = '\0';
bname = strdup( tok+1 );
}
ifd = inotify_init1( 0 ); // 初始化监视器设置为阻塞读取(无选项)
if( ifd < 0 ) {
fprintf( stderr, "### ERR ### 无法初始化文件监视 %s\n", strerror( errno ) );
} else {
wfd = inotify_add_watch( ifd, dname, IN_MOVED_TO | IN_CLOSE_WRITE ); // 我们只关心关闭写入更改
}
}
static int register_log_change_notify(const char *fileName)
{
pthread_attr_t cb_attr;
pthread_t tid;
pthread_attr_init(&cb_attr);
pthread_attr_setdetachstate(&cb_attr, PTHREAD_CREATE_DETACHED);
printf("文件名是 %s\n", fileName);
return pthread_create(&tid, &cb_attr, &monitor_loglevel_change_handler, (void *)fileName);
}
int enable_log_change_notify(const char* fileName)
{
int ret = -1;
struct stat fileInfo;
printf("文件名是 %s\n", fileName); // 打印正常
if (lstat(fileName, &fileInfo) == 0 )
{
ret = register_log_change_notify(fileName);
}
return ret;
}
void dynamic_log_level_change()
{
char *logFile_Name = read_env_param("TESTSHA");
char* log_level_init=NULL;
if(logFile_Name)
{
printf("logFile_Name 是:%s\n", logFile_Name);
free(log_level_init);
}
enable_log_change_notify(logFile_Name);
free(logFile_Name);
}
void init_log() {
int log_change_monitor = 0;
dynamic_log_level_change();
}
int main()
{
init_log();
sleep(50);
}
完整代码在此处:sctpThread.cpp
英文:
I am trying to print value of argument which is provided to the thread function "monitor_loglevel_change_handler" as a last param in pthread_create()
but it prints garbage instead of proper value. However, that is provided and printed properly earlier in the code see the comments
****(Updated my code further with minimum reproducible example as asked by others. Note I have put sleep intentionally in the main program so that thread function gets chance to run)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/inotify.h>
#include <errno.h>
#include <sys/stat.h>
char *read_env_param(const char*envkey)
{
if(envkey)
{
char *value = getenv(envkey);
if(value)
return strdup(value);
}
return NULL;
}
static void * monitor_loglevel_change_handler(void* arg)
{
char *fileName = (char*) arg;
int ifd; // the inotify file des
int wfd; // the watched file des
ssize_t n = 0;
char* dname=NULL; // directory name
char* bname = NULL; // basename
char* tok=NULL;
printf("Value of arguments: %s\n", (char*) arg); // --------> prints nothing why??
dname = strdup( fileName); // defrock the file name into dir and basename
if( (tok = strrchr( dname, '/' )) != NULL ) {
*tok = '\0';
bname = strdup( tok+1 );
}
ifd = inotify_init1( 0 ); // initialise watcher setting blocking read (no option)
if( ifd < 0 ) {
fprintf( stderr, "### ERR ### unable to initialise file watch %s\n", strerror( errno ) );
} else {
wfd = inotify_add_watch( ifd, dname, IN_MOVED_TO | IN_CLOSE_WRITE ); // we only care about close write changes
}
}
static int register_log_change_notify(const char *fileName)
{
pthread_attr_t cb_attr;
pthread_t tid;
pthread_attr_init(&cb_attr);
pthread_attr_setdetachstate(&cb_attr,PTHREAD_CREATE_DETACHED);
printf("file name is %s\n", fileName);
return pthread_create(&tid, &cb_attr,&monitor_loglevel_change_handler,(void *)fileName);
}
int enable_log_change_notify(const char* fileName)
{
int ret = -1;
struct stat fileInfo;
printf("filename is %s\n", fileName); // ----> prints properly
if ( lstat(fileName,&fileInfo) == 0 )
{
ret = register_log_change_notify(fileName);
}
return ret;
}
void dynamic_log_level_change()
{
char *logFile_Name = read_env_param("TESTSHA");
char* log_level_init=NULL;
if(logFile_Name)
{
printf("logFile_Name is :%s\n", logFile_Name);
free(log_level_init);
}
enable_log_change_notify(logFile_Name);
free(logFile_Name);
}
void init_log() {
int log_change_monitor = 0;
dynamic_log_level_change();
}
int main()
{
init_log();
sleep(50);
}
full code of above is here sctpThread.cpp
答案1
得分: 3
free(logFile_Name);
释放内存,它不再有效。
简单的解决方案是将内存所有权转移给线程。
return pthread_create(&tid, &cb_attr, &monitor_loglevel_change_handler,
// 分配新内存
strdup(fileName));
然后线程负责释放:
static void * monitor_loglevel_change_handler(void* arg) {
.... blabla .......
free(arg);
}
英文:
> free(logFile_Name);
You are freeing the memory, it is no longer valid.
The simple solution is to transfer ownership for the memory to the thread.
return pthread_create(&tid, &cb_attr,&monitor_loglevel_change_handler,
// allocate new memory dynamically
strdup(fileName));
And then the thread is responsible for free-ing:
static void * monitor_loglevel_change_handler(void* arg) {
.... blabla .......
free(arg);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论