gpt4 book ai didi

c - 使用 C 示例运行多线程时出错

转载 作者:行者123 更新时间:2023-11-30 18:12:28 26 4
gpt4 key购买 nike

我发现了一个多线程编程的示例,它有助于确定给定整数 n 的素数。它还会将线程数作为用户的输入。但问题是当我尝试执行它时给出我遇到了一些很难解决的错误。有人可以帮忙吗?我是编码新手,因此我们将不胜感激任何类型的帮助和建议。

 #include <stdio.h>
#include <math.h>
#include <pthread.h> // required for threads usage

#define MAX_N 100000000
#define MAX_THREADS 25


int nthreads, n, prime[MAX_N+1], nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];

// "crosses out" all odd multiples of k
void crossout(int k)
{ int i;
for (i = 3; i*k <= n; i += 2) {
prime[i*k] = 0;
}
}

// each thread runs this routine
void *worker(int tn) // tn is the thread number (0,1,...)
{ int lim,base,
work = 0; // amount of work done by this thread
// no need to check multipliers bigger than sqrt(n)
lim = sqrt(n);
do {

pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase += 2;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
// don't bother crossing out if base known composite
if (prime[base]) {
crossout(base);
work++; // log work done by this thread
}
}
else return work;
} while (1);
}

main(int argc, char **argv)
{ int nprimes, // number of primes found
i,work;
n = atoi(argv[1]);
nthreads = atoi(argv[2]);

for (i = 3; i <= n; i++) {
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
nextbase = 3;
// get threads started
for (i = 0; i < nthreads; i++) {

pthread_create(&id[i],NULL,worker,i);
}


for (i = 0; i < nthreads; i++) {

pthread_join(id[i],&work);
printf("%d values of base done\n",work);
}


nprimes = 1;
for (i = 3; i <= n; i++)
if (prime[i]) {
nprimes++;
}
printf("the number of primes found was %d\n",nprimes);
}

编译时出现以下错误:

 In function ‘worker’:
Primes.c:67:12: warning: return makes pointer from integer without a cast [enabled by default]
else return work;
^
Primes.c: In function ‘main’:
Primes.c:88:7: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int)’
extern int pthread_create (pthread_t *__restrict __newthread,
^
Primes.c:88:7: warning: passing argument 4 of ‘pthread_create’ makes pointer from integer without a cast [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * __restrict__’ but argument is of type ‘int’

最佳答案

使用:gcc -c -Wall -Wextra -Wconversion -std=gnu99 %f

哪里%f是正在编译的文件的名称

编译器输出以下消息。

我为每条消息添加了一些评论,以指导您如何解决问题。

编译器警告消息:

:28:14: warning: conversion to 'int' from 'double' may alter its' value [-Wconversion]

lim = sqrt(n);

功能:sqrt()返回“double”,但“lim”被声明为“int”

建议:将返回值转换为“int”

lim = (int)sqrt(n);

编译器警告消息:

:43:12: warning: return makes pointer from integer without a cast [enbled by default]

else return work;
  1. 来自 worker() 的返回类型功能是void*
  2. 始终退出worker()功能由:

    pthread_exit( &work );

编译器警告消息:

:24:18: warning: unused parameter 'tn' [-Wunused-parameter]

表示未使用参数“tn”。通过在该函数中插入以下行来解决此问题:

(void)tn;

编译器警告消息:

47:1: warning: return type defaults to 'int' [enabled by default]

main() 函数的签名不正确。如果不使用环境参数(几乎从未使用过),则只有 2 个有效的 main() 签名和 1 个可选签名。

根据您的程序需要使用正确的签名。

int main( void )
int main( int argc, char *argv[] )
int main() // optional signature

编译器警告消息:

50:4: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration]

表示头文件:stdlib.h尚未#include 建议在文件顶部插入:

#include <stdlib.h>

编译器警告消息:

61:7: warning: passing argument 3 of 'pthread_create' from incompatible pointer type [enabled by default]

表示函数的第三个参数:pthread_create()不是一个空指针。建议:

pthread_create(&id[i],NULL,worker,(void*)&i);

编译器警告消息:

67:7: warning: passing argument 2 of 'pthread_join' from incompatible pointer type [enabled by default]

意味着变量“work”应该在文件全局空间中声明,而不是在线程函数中,如下所示:

void * work;

还有其他编译器警告消息输出,但上面的将消除它们。

即始终从第一条编译器消息开始,修复该消息,然后重新编译。然后修复新的第一条消息。

通过注意所发布代码中调用的系统函数的手册页,可以避免大多数代码语法问题。

注意:crossout()函数的逻辑不正确。代码需要从 k+k 开始,继续直到 k<=n并逐步k+=k即:

for( int k=i+i; k<(n+1); k+=k )

代码似乎试图实现 eratosthenes sieve for prime numbers谷歌了解详细信息。

除非您需要使用线程,否则不要使用线程,它们只会由于所有上下文交换等而减慢速度。

这段代码逻辑:

for (i = 3; i <= n; i++)  
{
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}

似乎是错误的,一方面,数组 prime[]最初全为 0,因为它位于文件全局空间中。据我所知,根本不需要该代码块。

因为work变量将位于文件全局空间中,建议使用数组

void* work[ nthreads ];

然后就有线程函数:worker()实际上使用传递的参数来选择要更新数组中的哪些条目。

关于c - 使用 C 示例运行多线程时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35585427/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com