Pthread参数

时间:2012-03-25 01:01:00

标签: c multithreading pthreads

我遇到了将参数传递给新线程的问题,我有以下内容

 doRowOffset[0] = 0;
 for(threads = 1; threads < NUMTHREADS; threads++){
      doRowOffset[threads] = threads;
      printf("Do row: %d\n", doRowOffset[threads]);
      pthread_create(&threadHandler[threads], NULL, multiplyRows, (void *) &doRowOffset[threads]);
 }

void * multiplyRows(void * dealWithRows){
        int offset = *((int *) dealWithRows);
        printf("%d\n", *((int *) dealWithRows));
        printf("Offset: %d\n", offset);
        printf("Size: %d\n", partitionSize/NUMTHREADS);
        printf("Calculated Offset: %d\n", offset*partitionSize/NUMTHREADS);
        ...

现在我希望看到以下输出

行:1
1
偏移量:1
尺寸:2
计算的偏差:2

然而,当我进入线程时,我继续获取垃圾值或者为dealWithRows获取0,我在参数传递方面做错了吗?

2 个答案:

答案 0 :(得分:2)

如果doRowOffsetint,您不应该看到垃圾,除非创建功能的线程完成并且您已分配变量堆栈,它被覆盖。

但请注意,只有一个变量,并且您正在传递其地址,因此当线程启动时,它可以看到更新的值。

传递实际值:

pthread_create(&threadHandler[threads], NULL, multiplyRows, (void *) threads);

void * multiplyRows(void * dealWithRows){
    int offset = (int) dealWithRows);
}

答案 1 :(得分:2)

如果你传递了一个正在变化的变量的地址,你必须期望它可能会改变你: - )

可能发生的是你将doRowOffset设置为1(例如)然后启动线程。在该线程启动并取消引用其指针之前,您将为下一个线程更改doRowOffset

然后,当第一个线程最终取消引用该地址时,您已经更改了基础值。

有两种方法可以解决这个问题。第一种是同步主线程和子线程,以便主线程等待,直到子项取消引用变量并在本地存储该值。只有这样,主线程才会改变它即将启动的下一个线程的变量。但是,这种做法违背了线程的目的: - )

另一种方法是将实际的整数值(不是地址)转换为void指针,该指针将传递给线程函数。这意味着该值将被复制到线程函数的堆栈而不是地址,然后主线程将无法影响它。

类似的东西:

pthread_create (&threadHandler[threads], NULL, multiplyRows,
    (void *) doRowOffset); // <<-- Note, removed the '&'.

在主线程中:

int offset = (int) dealWithRows;

在子线程中。