【问题标题】:lvalue required as unary '&" operand需要左值作为一元“&”操作数
【发布时间】:2019-01-24 17:57:30
【问题描述】:

我的项目有问题,它应该使用线程将每一行相加,然后将所有内容相加,但我收到一个错误,提示 lvalue required as unary '&" 操作数

pthread_create(&tid, NULL, &sum_line(0), NULL);

我尝试了一些方法,但无法解决,有什么想法吗?谢谢

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
static void * sum_line(int nr_line);

int Sum;
int A[4][4];

int main() {
  pthread_t tid;
  Sum=0;
  printf("\nOrig thread tid(%d) Sum=%d", pthread_self(), Sum);
  pthread_create(&tid, NULL, &sum_line(0), NULL);
  printf("\nChild thread was created tid(%d)", tid);
  pthread_join(tid,NULL);
  printf("\nOrig thread tid(%d)-->Child thread ended tid(%d) Sum=%d",pthread_self(), tid, Sum);
  printf("\n");

}

static void * sum_line(int nr_line) {
    int i;
    for(i=0;i<4;i++) {
        Sum=Sum+A[i];
        printf("\nChild thread tid(%d), i=%d, Sum=%d",pthread_self(),i,Sum);
        sleep(2);
    }
    printf("\nChild thread tid(%d)--> ending", pthread_self());
}

【问题讨论】:

  • &amp;sum_line(0) - 这应该给什么?
  • void * sum_line() 缺少 return 语句。
  • pthread_create(&amp;tid, NULL, sum_line, (void*)0),这将导致 sum_line 被调用,下一个参数将是同一函数的第一个参数。可能最好将您的 int nr_line 参数也声明为 void*,然后将其转换为该值。

标签: c linux pthreads


【解决方案1】:

将函数指针传递给pthread_create()

只写sum_line,而不是&amp;sum_line(0)

pthread_create() 函数需要一个指向线程函数的指针——即函数名——而不是调用函数的结果。 pthread_create() 函数会安排新线程调用该函数,但它需要一个函数指针。

另外,线程函数的签名必须是:

void *function(void *arg);

该函数还应该返回一个值——在右大括号之前添加return 0;

你将一个空指针传递给函数;你不能指望它像int nr_line 一样工作。您需要做一些花哨的步法才能获得该功能的数字。 有两个主要选项:

要么

int nr_line = 247;

pthread_create(&tid, NULL, sum_line, &nr_line);

函数如下所示:

void *sum_line(void *arg)
{
    int nr_line = *(int *)arg;
    …
    return 0;
}

只需确保在启动多个线程时每个线程都获得指向不同对象的指针。

或者

uintptr_t nr_line = 247;
pthread_create(&tid, NULL, sum_line, (void *)nr_line);

或者:

int nr_line = 247;
pthread_create(&tid, NULL, sum_line, (void *)(uintptr_t)nr_line);

然后函数看起来像:

void *sum_line(void *arg)
{
    int nr_line = (uintptr_t)arg;
    …
    return 0;
}

双重转换避免了编译器关于将不同大小的整数转换为指针的警告。

请注意,pthread_create() 会像调用 void *function(void *args) 一样调用函数,因此将任何其他类型的函数指针传递给它,即使使用 (void (*)(void *)) 进行强制转换,也是作弊并导致未定义的行为。

【讨论】:

  • 最好分配 arg 以在 sum_line 中提供和释放它,不要将 int 转换为 void * 并反转(64b 中的 oupps)也不冒本地 var 消失的风险(此处受连接保护)。只是我的 2 美分 ;-)
  • @bruno — 有很多方法可以处理它。我概述的是两种可接受的方式(IMO),我注意到确保多个线程每个都有一个单独的参数很重要。分配是另一种选择;这不是必需的。例如,拥有一个合适类型的数组的局部变量并将指向数组不同元素的指针传递给每个线程是可行的。当然,你必须确保变量的生命周期得到适当的尊重——情况总是如此。如果你分配,你也必须释放。这里没有必要。
  • 我只是希望 ton 能够理解所有这些,很多人复制/粘贴代码而不检查完整上下文是否相同,我当然不知道你 ^^ 提出一个健壮的代码以相同的价格(几个 malloc 和免费没什么)限制了未来可能出现的问题
  • 因为我自己通常不会使用malloc()free()——但这取决于上下文——我不会推荐它。我接受这是完全可能的。启动单个线程是不寻常的——它演示了“训练练习”,尤其是当线程函数在其循环中间有sleep(2); 时。建议的更改将使培训练习发挥作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
相关资源
最近更新 更多