我从一本高级 Linux 编程书中得到了这段代码。当我尝试在Linux 64位环境下执行代码时,which_prime
之后变量被损坏(更改为 0)pthread_join()
函数调用。
在这个例子中为什么值which_prime
运行 pthread_join 后损坏?
一般来说,即使我们调用其他函数,我们也可以在 main 内部安全地使用传递给 pthread_create 函数的第四个参数pthread_join()
?
#include <pthread.h>
#include <stdio.h>
/* Compute successive prime numbers (very inefficiently). Return the
Nth prime number, where N is the value pointed to by *ARG. */
void* compute_prime (void* arg)
{
int candidate = 2;
int n = *((int*) arg);
while (1) {
int factor;
int is_prime = 1;
/* Test primality by successive division. */
for (factor = 2; factor < candidate; ++factor)
if (candidate % factor == 0) {
is_prime = 0;
break;
}
/* Is this the prime number we’re looking for? */
if (is_prime) {
if (--n == 0)
/* Return the desired prime number as the thread return value. */
return (void*) candidate;
}
++candidate;
}
return NULL;
}
int main ()
{
pthread_t thread;
int which_prime = 5000;
int prime;
/* Start the computing thread, up to the 5,000th prime number. */
pthread_create (&thread, NULL, &compute_prime, &which_prime);
/* Do some other work here... */
/* Wait for the prime number thread to complete, and get the result. */
pthread_join (thread, (void*) &prime);
/* Print the largest prime it computed. */
printf(“The %dth prime number is %d.\n”, which_prime, prime);
return 0;
}
我们已经到了一个时间点,在不同的货币之间进行转换不再安全。int
and a pointer
。这是因为在 64 位系统中,指针是 64 位的,但是int
只有 32 位。
所以假设32位int
和 64 位指针,这就是您的代码中发生的情况。第二个参数pthread_join
是一个指向指针的指针。换句话说,您应该传递指针的地址(64 位值的地址)。相反,您传递的地址是prime
(32 位值的地址)。什么时候pthread_join
写入结果,它会覆盖which_prime
, 因为which_prime
如下prime
在记忆中。
要解决此问题,您需要避免在之间进行转换int
s 和指针。一种方法是避免使用第二个参数pthread_join
,如以下代码所示。
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 20
typedef struct
{
int success;
int input;
int output;
} stData;
void *doSomething( void *arg )
{
stData *dataptr = arg;
dataptr->success = 1;
dataptr->output = dataptr->input * 2;
return NULL;
}
int main( void )
{
int i;
pthread_t id[NUM_THREADS];
stData data[NUM_THREADS] = {{0}};
for ( i = 0; i < NUM_THREADS; i++ )
{
data[i].input = i + 1;
pthread_create( &id[i], NULL, doSomething, &data[i] );
}
for ( i = 0; i < NUM_THREADS; i++ )
{
pthread_join( id[i], NULL );
if ( data[i].success )
printf( "thread %2d: input=%2d output=%2d\n", i+1, data[i].input, data[i].output );
else
printf( "thread %2d: failed\n", i+1 );
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)