pthread_create 跳过或重复
pthread_create skips or repeats
pthread_create 函数被跳过或有时被调用两次。
我要解决的问题是:
给定一个全局数组,其中包含从 1 到 100 的数字。您需要创建 10 个线程,每个线程必须计算 10 个数字的平方和。
线程 1 必须计算从 1 到 10
线程 2 必须计算从 11 到 20
...等等。
每个线程必须 return 其单独的总和到一个用零初始化的全局变量总和。
我的尝试:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<semaphore.h>
int arr[100];
sem_t s;
int sum=0;
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));
int k;
printf("j: %d\n",j);
int temp=0;
for(k=j*10;k<(j*10)+10;k++){
temp=temp+(arr[k]*arr[k]);
}
sum+=temp;
printf("sum: %d j: %d\n\n",sum,j);
sem_post(&s);
pthread_exit(NULL);
}
int main(){
sem_init(&s,0,1);
pthread_t threads_array[10];
int i=0;
int *k=(int *)malloc(sizeof(int));
for(i=0;i<100;i++){
arr[i]=i+1;
}
int temp=0,temp_i;
for(i=0;i<10;i++){
(*k)=i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
for(i=0;i<10;i++){
pthread_join(threads_array[i],NULL);
}
printf("%d",sum);
return 0;
}
我用过信号量。这样一次只有一个线程访问全局资源。
我得到的输出是:
Output screen
我的问题是为什么它会重复一些值并跳过一些值?我没有正确使用 pthread_create?
我也试过每次都使用新的k值:
for(i=0;i<2;i++){
int *k=&i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
此代码将 k
的相同地址传递给每个线程,但 它更改了该内存中的值:
for(i=0;i<10;i++){
(*k)=i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
这段代码运行时
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));
.
.
.
该值可能已更改,因为主线程更改了它。
这会更好,因为它传递了 i
的 值 ,但这取决于 intptr_t
的存在和平台特定的行为允许转换回 int
,因此它不严格符合 C 代码:
for(i=0;i<10;i++){
pthread_create(&(threads_array[i]),NULL,calculate,(void*)(intptr_t)i);
}
和
void *calculate(void *i){
sem_wait(&s);
int j= (intptr_t)i;
将i
的值作为void *
指针值传递。
但如果 intptr_t
存在,这样更好:
intptr_t i;
.
.
.
for(i=0;i<10;i++){
pthread_create(&(threads_array[i]),NULL,calculate,(void*)i);
}
和
void *calculate(void *i){
sem_wait(&s);
intptr_t j= (intptr_t)i;
实际上,没有多少平台不再适用这种方法。
或者,在严格符合 C 的情况下,要传递实际 int
值的地址,您需要为每个线程保证存在的单独 int
当线程为 运行:
// this is a local variable, but since it's in the same scope as
// both pthread_create() and pthread_join(), it will still exist
// for the entire lifetime of each thread created
int threadnum[10];
for(i=0;i<10;i++){
threadnum[i]=i;
pthread_create(&(threads_array[i]),NULL,calculate,(void*)&(threadnum[i]));
}
和
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));
pthread_create 函数被跳过或有时被调用两次。 我要解决的问题是:
给定一个全局数组,其中包含从 1 到 100 的数字。您需要创建 10 个线程,每个线程必须计算 10 个数字的平方和。
线程 1 必须计算从 1 到 10
线程 2 必须计算从 11 到 20
...等等。
每个线程必须 return 其单独的总和到一个用零初始化的全局变量总和。
我的尝试:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<semaphore.h>
int arr[100];
sem_t s;
int sum=0;
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));
int k;
printf("j: %d\n",j);
int temp=0;
for(k=j*10;k<(j*10)+10;k++){
temp=temp+(arr[k]*arr[k]);
}
sum+=temp;
printf("sum: %d j: %d\n\n",sum,j);
sem_post(&s);
pthread_exit(NULL);
}
int main(){
sem_init(&s,0,1);
pthread_t threads_array[10];
int i=0;
int *k=(int *)malloc(sizeof(int));
for(i=0;i<100;i++){
arr[i]=i+1;
}
int temp=0,temp_i;
for(i=0;i<10;i++){
(*k)=i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
for(i=0;i<10;i++){
pthread_join(threads_array[i],NULL);
}
printf("%d",sum);
return 0;
}
我用过信号量。这样一次只有一个线程访问全局资源。
我得到的输出是:
Output screen
我的问题是为什么它会重复一些值并跳过一些值?我没有正确使用 pthread_create?
我也试过每次都使用新的k值:
for(i=0;i<2;i++){
int *k=&i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
此代码将 k
的相同地址传递给每个线程,但 它更改了该内存中的值:
for(i=0;i<10;i++){
(*k)=i;
printf("k: %d\n",(*k));
pthread_create(&(threads_array[i]),NULL,calculate,(void*)k);
}
这段代码运行时
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));
.
.
.
该值可能已更改,因为主线程更改了它。
这会更好,因为它传递了 i
的 值 ,但这取决于 intptr_t
的存在和平台特定的行为允许转换回 int
,因此它不严格符合 C 代码:
for(i=0;i<10;i++){
pthread_create(&(threads_array[i]),NULL,calculate,(void*)(intptr_t)i);
}
和
void *calculate(void *i){
sem_wait(&s);
int j= (intptr_t)i;
将i
的值作为void *
指针值传递。
但如果 intptr_t
存在,这样更好:
intptr_t i;
.
.
.
for(i=0;i<10;i++){
pthread_create(&(threads_array[i]),NULL,calculate,(void*)i);
}
和
void *calculate(void *i){
sem_wait(&s);
intptr_t j= (intptr_t)i;
实际上,没有多少平台不再适用这种方法。
或者,在严格符合 C 的情况下,要传递实际 int
值的地址,您需要为每个线程保证存在的单独 int
当线程为 运行:
// this is a local variable, but since it's in the same scope as
// both pthread_create() and pthread_join(), it will still exist
// for the entire lifetime of each thread created
int threadnum[10];
for(i=0;i<10;i++){
threadnum[i]=i;
pthread_create(&(threads_array[i]),NULL,calculate,(void*)&(threadnum[i]));
}
和
void *calculate(void *i){
sem_wait(&s);
int j=(*((int*)i));