我正在尝试使用线程池作为worker来构建TCP / IP侦听器。 基本的东西不起作用,(cond_wait / cond_signal麻烦)所以我缩小了问题。但是随后的代码我得到了一个分段错误。
struct worker {
pthread_t tid;
pthread_cond_t worker_cv;
pthread_mutex_t worker_mutex;
int worker_flag;
};
typedef struct worker worker_t;
void initialize_flag( worker_t * w)
{
printf( "Mutex (%d)\n", (int) sizeof w->worker_mutex );
pthread_mutex_init (& w->worker_mutex, NULL);
printf( "Cond (%d)\n", (int) sizeof w->worker_cv );
pthread_cond_init (& w->worker_cv, NULL);
printf( "Flag\n" );
w->worker_flag = 0;
}
SF发生在“Mutex”的printf之后。 我传递给initialize_flag()的指针是全局的,并且在main()中被malloc化,以模仿我正在寻找的真实行为。
TIA ((编辑:取自@marcelo的回答): 以下是您要求的相关代码部分
worker_t * worker;
main( )
{
worker = malloc( sizeof( worker_t ) );
if ( worker == NULL ) {
fprintf( stderr, "malloc\n" );
exit(1);
}
fprintf( stdout, "Zero\n" );
memset( & worker, 0, sizeof( worker_t ) );
fprintf( stdout, "Init\n" );
initialize_flag( worker );
答案 0 :(得分:2)
我看不出代码有什么问题,所以我想这可能是因为w->worker
没有将内存块指向pthread_mutex_t的大小。
您没有显示initialize_flag
的调用方式,但它应该类似于:
worker_t * w;
w = malloc(sizeof worker_t);
...
initialize_flag(w);
你说你已经在main()
分配了这一切。我可以建议您这样做:
worker_t test;
initialize_flag(&test);
看看是否有段错误?最好不要在main()
中做任何其他事情。
另外,我建议您在调试器中运行并打印w->worker_mutex
,或者创建函数的第一行:
printf( "Mutex (%d:%p)\n", (int) sizeof w->worker_mutex, &(w->worker_mutex) );
答案 1 :(得分:1)
memset( & worker, 0, sizeof( worker_t ) ); // zero worker
与不是与
相同memset( worker, 0, sizeof( worker_t ) ); // zero the objected worker designates
您的memset
来电正在调用worker
之前立即将NULL
设为initialize_flag
。
根本不需要动态分配,只需静态分配worker
,它最初会归零:
worker_t worker;
int main(void)
{
fprintf( stdout, "Init\n" );
initialize_flag( &worker );
答案 2 :(得分:1)
代码通过将未分配的内存设置为零来激发未定义的行为:
memset( & worker, 0, sizeof( worker_t ) );
上面这一行最有可能通过将sizeof(worker_t)
字节 写入指向{{1}的指针的地址 来掩盖程序的内存管理。已经分配了字节,而不是指针所指向的位置。
这样做也会覆盖对内存分配的引用。它不再可访问,因此不能再worker_t
ed并且程序泄漏了这个内存。
将新分配的结构清零:
free()
或
memset(worker, 0, sizeof(worker_t ));
或使用memset(worker, 0, sizeof(*worker));
在分配时将其初始化为零(无需再调用calloc()
:
memset(worker, 0, ...)
或
worker = calloc( 1, sizeof(worker_t));
您可能想知道为什么代码还没有在这里:
worker = calloc( 1, sizeof(*worker));
请注意,上面使用的printf( "Mutex (%d)\n", (int) sizeof w->worker_mutex );
表达式在编译期间已经计算,因为它是常量。
所以1 st 时间(sizeof(...)
- 指针)NULL
试图被解除引用是在这里:
w
这样做会导致观察到的分割vilolation。