使用 pthread_mutex_lock 时遇到问题

Trouble using pthread_mutex_lock

大学刚开始学线程,好像不太了解

我想让我的代码获取参数并检查它们是偶数还是质数,如果是,则打印它们。另外对这些数字中的每一个求和。

这是代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define something 10

pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
int snrp=0;
int sprim=0;

void * verif(void* argv){
    pthread_mutex_lock(&lock);
    int x=*(int*)argv;
    if (x%2==0){
        printf("%d is even\n",x);
        snrp+=x;
    }
    else{
        int ok=1;
        int d;
        if(x<1)
            ok=0;
        for(d=3;d*d<x;d+=2)
            if(x%d==0)
                ok=0;
        if(ok==0)
            return NULL;
        printf("%d is prime\n",x);
        sprim+=x;
    }
    pthread_mutex_unlock(&lock);
    sleep(1);
    return NULL;
}


int main(int argc,char* argv[]){

    pthread_t threads[something];
    int i,n;
    for(i=1;i<argc;i+=1){
        n=atoi(argv[i]);
        if(pthread_create(&threads[i],NULL,verif,(void*) &n))
            printf("Error");
    }
    for(i=1;i<argc;i+=1)
        pthread_join(threads[i],NULL);

    printf("Even numbers sum is %d \n",snrp);
    printf("Prime numbers sum is %d \n",sprim);
    pthread_mutex_destroy(&lock);
    return 0;

}

如果我使用例如参数 2,3,5 我得到输出:

5 is prime
5 is prime
5 is prime
Even numbers sum is 0 
Prime numbers sum is 15 

谁能解释一下为什么?

您的 verif 函数可以 return 而无需释放此处的锁:

if(ok==0)
     return NULL;

这将使锁永远持有,任何其他试图获取它的线程都将永远等待。

另外,这是错误的:

for(i=1;i<argc;i+=1){
n=atoi(argv[i]);
if(pthread_create(&threads[i],NULL,verif,(void*) &n))
    printf("Error");
}

您将 n 的地址传递给线程,但它应该如何处理该地址? n的值在这段代码中被修改,没有同步,所以新线程不能合法访问它。不是向线程传递 n 的地址,而是向它传递 n

@Darkmer

void * verif(void* argv){ pthread_mutex_lock(&lock); int x=*(int*)argv; printf("%p stores %d",argv,n); // 添加这一行。在你的代码中。

你会明白,每次你发送相同的地址,因此相同的 n(在你的样本中是 5)。为什么会这样?发生这种情况是因为在线程使用 n 之前,您在 main 函数中使用下一个命令行参数并行更改了它。

发生这种情况,因为在主程序中,您对所有三个参数使用了相同的 'n'。相反,推迟 atoi 函数并在 verif() 中使用它。直接从命令行参数传递 argv。我可以为您完成 pthread_create(..) 功能更改,但这是您的家庭作业。

祝你好运。

您为线程发送相同的参数。

int main(int argc,char* argv[]){

    pthread_t threads[something];
    int i;
    int n[3] = {2, 3, 5};
    for(i=0;i<3;i+=1)
    {
        if(pthread_create(&threads[i],NULL,verif,(void*) &n[i]))
            printf("Error");
    }
    for(i=0;i<3;i+=1)
        pthread_join(threads[i],NULL);

    printf("Even numbers sum is %d \n",snrp);
    printf("Prime numbers sum is %d \n",sprim);
    pthread_mutex_destroy(&lock);
    return 0;

}

通知:pthread_create(&threads[i],NULL,verif,(void*) &n[i])

这是 link: http://linux.die.net/man/3/pthread_create