1
#include <pthread.h>
#include <stdio.h>
#include <math.h>
#include <stdio.h>
#include <pthread.h>
#define NO_OF_THREADS 5

void print_function(int* i)
{
 int count;
 for(count=0; count<10; count++)
  printf("Hello world from thread %d\n",*i);
 pthread_exit(NULL);
}

int main()
{
 pthread_t printThreads[NO_OF_THREADS];
 int thread_no[NO_OF_THREADS];
 int i;

 for(i=0; i<NO_OF_THREADS; i++)
 {
  thread_no[i] = i;
  pthread_create(&printThreads[i], NULL, print_function,&thread_no[i]);
 }

 int j;
 for(j=0;j<NO_OF_THREADS;j++)
  pthread_join(printThreads[j],NULL);
 puts("Main over and out");
 return 0;
}

不只是将计数器变量的地址i直接作为pthread_create函数的参数传递,而是首先将其分配给数组的未使用槽,然后将数组元素的地址作为参数传递。这样做是为了避免i在父线程和创建的线程之间访问竞争条件。解释如果变量i直接传递给线程会发生什么。

4

4 回答 4

1

变量可以“直接”传递而没有风险,只要它成功地转换为 和 from void *,当然。如果使用这种方法,则不需要每线程缓冲。

传递单个位置的地址i( in的地址main()),其内容随着创建更多线程而变化,这当然是疯狂的。

于 2013-10-03T11:56:58.723 回答
0

目的是thread_no[]什么?你想在任何地方改变它吗?如果不是(正如我在这里看到的那样),那么就不必担心任何竞争条件,因为您将不同的线程传递thread_no[i]给不同的线程,并且您在生成将其传递给的线程之前设置它的值。所以在产生线程thread_no[i]之前不会被传递或访问。i只是thread_no[i]不通过&thread_no[i]或只是通过i(因为它是相同的)。

于 2013-10-03T14:14:25.963 回答
0

您可以直接传递它没有问题,您必须将其转换为整数,因为它的类型是 void * in pthread_create

于 2013-10-03T11:58:21.317 回答
0

如果您将地址传递i给调用中的每个线程pthread_create(),那么您无法保证每个线程将在变量中看到什么值。线程 0 可能会看到诸如 2 或 3 之类的值,因为即使调用i0 时为 0,但当pthread_create()线程运行并读取变量时,主线程已经更改了该值。

例如,使用这个经过轻微修改的代码版本,我得到的输出是:

Hello world from thread 3
Hello world from thread 4
Hello world from thread 4
Hello world from thread 3
Hello world from thread 5
Hello world from thread 5
Hello world from thread 5
...
Hello world from thread 5
Hello world from thread 5
Hello world from thread 5
Main over and out

修改后的代码:

删除<math.h>and 重复<stdio.h>and <pthread.h>; 删除了thread_no变量;修复了线程函数的类型以匹配pthread_create()预期等。

#include <pthread.h>
#include <stdio.h>
#define NO_OF_THREADS 5

void *print_function(void *ip);
void *print_function(void *ip)
{
    int *i = ip;
    int count;
    for(count=0; count<10; count++)
        printf("Hello world from thread %d\n",*i);
    pthread_exit(NULL);
    return 0;
}

int main(void)
{
    pthread_t printThreads[NO_OF_THREADS];
    int i;

    for(i=0; i<NO_OF_THREADS; i++)
    {
        pthread_create(&printThreads[i], NULL, print_function,&i);
    }

    int j;
    for(j=0;j<NO_OF_THREADS;j++)
        pthread_join(printThreads[j],NULL);
    puts("Main over and out");
    return 0;
}

当我将代码修改为 printpthread_self()以及 时*i,我得到了输出:

0x10800f000: Hello world from thread 1
0x10800f000: Hello world from thread 4
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x10800f000: Hello world from thread 5
0x108092000: Hello world from thread 5
0x108115000: Hello world from thread 5
0x108198000: Hello world from thread 5
0x10821b000: Hello world from thread 5

其中四个线程只看到值 5;其中之一(可能是“线程 0”)也必须看到值 1 和 4。这种行为也是不确定的。这是另一次运行的开始:

0x10432b000: Hello world from thread 3
0x1043ae000: Hello world from thread 4
0x104431000: Hello world from thread 4
0x1044b4000: Hello world from thread 4
0x104537000: Hello world from thread 5
0x10432b000: Hello world from thread 5
0x1043ae000: Hello world from thread 5

在这两种情况下,其余条目都是 echoing 的各种线程5

于 2013-10-03T14:33:41.050 回答