提供给线程函数的参数在pthread中打印垃圾值。

huangapple go评论145阅读模式
英文:

argument provided to the thread function prints garbage in pthread

问题

我正在尝试打印作为pthread_create()函数中的最后一个参数提供给线程函数"monitor_loglevel_change_handler"的参数的值,但它打印出垃圾而不是正确的值。然而,在代码的前面部分,它已经正确提供并打印了,详见注释

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <pthread.h>
  5. #include <sys/inotify.h>
  6. #include <errno.h>
  7. #include <sys/stat.h>
  8. char *read_env_param(const char* envkey)
  9. {
  10. if(envkey)
  11. {
  12. char *value = getenv(envkey);
  13. if(value)
  14. return strdup(value);
  15. }
  16. return NULL;
  17. }
  18. static void *monitor_loglevel_change_handler(void* arg)
  19. {
  20. char *fileName = (char*) arg;
  21. int ifd; // the inotify file des
  22. int wfd; // the watched file des
  23. ssize_t n = 0;
  24. char* dname=NULL; // directory name
  25. char* bname = NULL; // basename
  26. char* tok=NULL;
  27. printf("参数的值:%s\n", (char*) arg); // --------> 为什么什么都不打印??
  28. dname = strdup( fileName); // 解析文件名为目录名和基本文件名
  29. if( (tok = strrchr( dname, '/')) != NULL ) {
  30. *tok = '\0';
  31. bname = strdup( tok+1 );
  32. }
  33. ifd = inotify_init1( 0 ); // 初始化监视器设置为阻塞读取(无选项)
  34. if( ifd < 0 ) {
  35. fprintf( stderr, "### ERR ### 无法初始化文件监视 %s\n", strerror( errno ) );
  36. } else {
  37. wfd = inotify_add_watch( ifd, dname, IN_MOVED_TO | IN_CLOSE_WRITE ); // 我们只关心关闭写入更改
  38. }
  39. }
  40. static int register_log_change_notify(const char *fileName)
  41. {
  42. pthread_attr_t cb_attr;
  43. pthread_t tid;
  44. pthread_attr_init(&cb_attr);
  45. pthread_attr_setdetachstate(&cb_attr, PTHREAD_CREATE_DETACHED);
  46. printf("文件名是 %s\n", fileName);
  47. return pthread_create(&tid, &cb_attr, &monitor_loglevel_change_handler, (void *)fileName);
  48. }
  49. int enable_log_change_notify(const char* fileName)
  50. {
  51. int ret = -1;
  52. struct stat fileInfo;
  53. printf("文件名是 %s\n", fileName); // 打印正常
  54. if (lstat(fileName, &fileInfo) == 0 )
  55. {
  56. ret = register_log_change_notify(fileName);
  57. }
  58. return ret;
  59. }
  60. void dynamic_log_level_change()
  61. {
  62. char *logFile_Name = read_env_param("TESTSHA");
  63. char* log_level_init=NULL;
  64. if(logFile_Name)
  65. {
  66. printf("logFile_Name 是:%s\n", logFile_Name);
  67. free(log_level_init);
  68. }
  69. enable_log_change_notify(logFile_Name);
  70. free(logFile_Name);
  71. }
  72. void init_log() {
  73. int log_change_monitor = 0;
  74. dynamic_log_level_change();
  75. }
  76. int main()
  77. {
  78. init_log();
  79. sleep(50);
  80. }

完整代码在此处: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)

  1. #include&lt;stdio.h&gt;
  2. #include&lt;string.h&gt;
  3. #include&lt;stdlib.h&gt;
  4. #include&lt;pthread.h&gt;
  5. #include&lt;sys/inotify.h&gt;
  6. #include &lt;errno.h&gt;
  7. #include &lt;sys/stat.h&gt;
  8. char *read_env_param(const char*envkey)
  9. {
  10. if(envkey)
  11. {
  12. char *value = getenv(envkey);
  13. if(value)
  14. return strdup(value);
  15. }
  16. return NULL;
  17. }
  18. static void * monitor_loglevel_change_handler(void* arg)
  19. {
  20. char *fileName = (char*) arg;
  21. int ifd; // the inotify file des
  22. int wfd; // the watched file des
  23. ssize_t n = 0;
  24. char* dname=NULL; // directory name
  25. char* bname = NULL; // basename
  26. char* tok=NULL;
  27. printf(&quot;Value of arguments: %s\n&quot;, (char*) arg); // --------&gt; prints nothing why??
  28. dname = strdup( fileName); // defrock the file name into dir and basename
  29. if( (tok = strrchr( dname, &#39;/&#39; )) != NULL ) {
  30. *tok = &#39;\0&#39;;
  31. bname = strdup( tok+1 );
  32. }
  33. ifd = inotify_init1( 0 ); // initialise watcher setting blocking read (no option)
  34. if( ifd &lt; 0 ) {
  35. fprintf( stderr, &quot;### ERR ### unable to initialise file watch %s\n&quot;, strerror( errno ) );
  36. } else {
  37. wfd = inotify_add_watch( ifd, dname, IN_MOVED_TO | IN_CLOSE_WRITE ); // we only care about close write changes
  38. }
  39. }
  40. static int register_log_change_notify(const char *fileName)
  41. {
  42. pthread_attr_t cb_attr;
  43. pthread_t tid;
  44. pthread_attr_init(&amp;cb_attr);
  45. pthread_attr_setdetachstate(&amp;cb_attr,PTHREAD_CREATE_DETACHED);
  46. printf(&quot;file name is %s\n&quot;, fileName);
  47. return pthread_create(&amp;tid, &amp;cb_attr,&amp;monitor_loglevel_change_handler,(void *)fileName);
  48. }
  49. int enable_log_change_notify(const char* fileName)
  50. {
  51. int ret = -1;
  52. struct stat fileInfo;
  53. printf(&quot;filename is %s\n&quot;, fileName); // ----&gt; prints properly
  54. if ( lstat(fileName,&amp;fileInfo) == 0 )
  55. {
  56. ret = register_log_change_notify(fileName);
  57. }
  58. return ret;
  59. }
  60. void dynamic_log_level_change()
  61. {
  62. char *logFile_Name = read_env_param(&quot;TESTSHA&quot;);
  63. char* log_level_init=NULL;
  64. if(logFile_Name)
  65. {
  66. printf(&quot;logFile_Name is :%s\n&quot;, logFile_Name);
  67. free(log_level_init);
  68. }
  69. enable_log_change_notify(logFile_Name);
  70. free(logFile_Name);
  71. }
  72. void init_log() {
  73. int log_change_monitor = 0;
  74. dynamic_log_level_change();
  75. }
  76. int main()
  77. {
  78. init_log();
  79. sleep(50);
  80. }

full code of above is here sctpThread.cpp

答案1

得分: 3

  1. free(logFile_Name);

释放内存,它不再有效。


简单的解决方案是将内存所有权转移给线程。

  1. return pthread_create(&tid, &cb_attr, &monitor_loglevel_change_handler,
  2. // 分配新内存
  3. strdup(fileName));

然后线程负责释放:

  1. static void * monitor_loglevel_change_handler(void* arg) {
  2. .... blabla .......
  3. free(arg);
  4. }
英文:

> 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.

  1. return pthread_create(&amp;tid, &amp;cb_attr,&amp;monitor_loglevel_change_handler,
  2. // allocate new memory dynamically
  3. strdup(fileName));

And then the thread is responsible for free-ing:

  1. static void * monitor_loglevel_change_handler(void* arg) {
  2. .... blabla .......
  3. free(arg);
  4. }

huangapple
  • 本文由 发表于 2023年8月10日 20:51:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76875898.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定