#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
直接传递给线程会发生什么。
答案 0 :(得分:1)
变量可以“直接”传递而没有风险,只要它成功地与void *
进行转换,当然。如果使用该方法,则不需要每线程缓冲。
传递单个位置的地址(i
中main()
的地址),其内容随着更多线程的创建而变化,当然是疯狂的。
答案 1 :(得分:0)
你可以直接传递它没有问题,你必须把它强制转换为整数,因为它的类型是pthread_create中的void *
答案 2 :(得分:0)
thread_no[]
的目的是什么?你想在任何地方改变它吗?如果不是(并且正如我在这里看到的那样),那么不用担心任何竞争条件,因为你将不同的thread_no[i]
传递给不同的线程,并且在产生传递它的线程之前设置它的值。因此,在thread_no[i]
线程生成之前,不会传递或访问i
。只需通过thread_no[i]
而不是&thread_no[i]
或只是通过i
(因为它是相同的)。
答案 3 :(得分:0)
如果将i
的地址传递给pthread_create()
调用中的每个线程,则无法保证每个线程在变量中看到的值。可能是线程0将看到诸如2或3之类的值,因为即使i
在调用pthread_create()
时为0,在线程运行并读取变量时,值也是已经被主线改变了。
例如,使用这个经过温和修改的代码版本,我得到的输出是:
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>
并重复<stdio.h>
和<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;
}
当我修改代码以打印pthread_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
在这两种情况下,其余条目都是回显5
的各种线程。