我正在尝试用线程池作为工人构建一个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( "Flagn" );
w->worker_flag = 0;
}
SF发生在" Mutex"的printf之后。我要传递给initialize_flag()的指针是一个全局,并且在main()中是malloc'ed,以模仿我正在寻找的真实行为。
tia((编辑:取自@marcelo的答案):这是您要求
的代码的相关部分worker_t * worker;
main( )
{
worker = malloc( sizeof( worker_t ) );
if ( worker == NULL ) {
fprintf( stderr, "mallocn" );
exit(1);
}
fprintf( stdout, "Zeron" );
memset( & worker, 0, sizeof( worker_t ) );
fprintf( stdout, "Initn" );
initialize_flag( worker );
我看不到代码有任何问题,所以我想这可能是因为 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);
看看是否segfaults?最好在main()
中不做其他任何事情。
另外,我建议您在调试器中运行并打印出w->worker_mutex
,或者制作功能的第一行:
printf( "Mutex (%d:%p)n", (int) sizeof w->worker_mutex, &(w->worker_mutex) );
代码通过将未分配的内存设置为零来激发不确定的行为:
memset( & worker, 0, sizeof( worker_t ) );
上面的行很可能通过将sizeof(worker_t)
字节编写到地址的指针中,而是将worker_t
字节已分配给的指针的地址来捣碎。指针指向的位置。
这样做也覆盖对内存分配的引用。它不再可以访问,因此不能再被free()
ED访问,并且程序泄漏了此内存。
零分配的结构为零:
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));
您可能想知道为什么代码在此处尚未cr绕:
printf( "Mutex (%d)n", (int) sizeof w->worker_mutex );
请注意,上述sizeof(...)
表达式是在编译时间内计算的,因为它是恒定的。
所以1 st 时间(NULL
-POINTER)w
正在尝试被解释:
pthread_mutex_init (& w->worker_mutex, NULL);
这样做会导致观察到的分割vilolation。
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, "Initn" );
initialize_flag( &worker );