在 Linux 上需要有关使用 C 进行多线程编程的帮助

Need help on Multi-threaded Programming with C on Linux

我开始学习 Linux 上的 C 多线程编程。下面是我的练习和我为每个线程执行 hello 函数的代码。请告诉我哪里出了问题。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
    
#define NUM_THREADS 4
     
void *hello(void * );
     
int main() {
  int j;
  pthread_t tid[NUM_THREADS];
     
  printf("My process ID %d\n", getpid());
  for (j = 0; j < NUM_THREADS; j++)
    pthread_create(&tid[j], NULL, hello, (void*)j); //original is pthread_create([1])
     
  for (int i = 0; i < NUM_THREADS; i++)
    pthread_join(tid[i], NULL); //original is pthread_join([2])
     
  return 0;
}
     
void *hello(void * my_id) {
  printf("Hello World from branch thread %d\n", *(int * ) my_id);
}

因为是填空题,下面只有两行会出错,下面两行是我加的。我认为是 (void*)j

    pthread_create(&tid[j], NULL, hello, (void*)j); //[1]
    pthread_join(tid[i], NULL); //[2]

[1] 正在创建带有 tid 的子线程,每个子线程执行带参数 j 的 hello 函数。

[2]是主线程只有在所有子线程结束后才结束

我没有这方面的预期输出。但是我有一个高级请求的预期输出(需要更改原始代码的某些部分,而不仅仅是填写[1]和[2])如下:

My process ID 127

Hello World from branch thread 0

Hello World from branch thread 1

Hello World from branch thread 2

Hello World from branch thread 3

我的错误是:

quang@quang-VirtualBox:~$ gcc exe2_1.c -o exe2_1 -pthread
exe2_1.c: In function ‘main’:
exe2_1.c:32:42: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   32 |     pthread_create(&tid[j], NULL, hello, (void*)j)

请理解我的第一个科目是Python,这是我的第二个科目(操作系统),我对C 的知识为零,但我的学校强迫我学习这个。我只需要固定的代码,这样我就可以提交了。

您没有指定预期的输出。解决方案取决于您是否期望从每个线程看到不同的数字,或者某些线程是否可能打印相同的数字。

要修复来自编译器的消息,您必须提供一个真正的指针。不仅仅是你转换为指针的一些整数。

如果你这样做

    int j = 1;
    pthread_create(&tid[j], NULL, hello, (void*)j);

这将导致 hello 被调用 1 其中包含一个整数值。但是 hello 认为,它是一个指针并试图取消引用它。 这行不通。

相反,您必须提供一些 int 变量的地址。 将相关行更改为

    pthread_create(&tid[j], NULL, hello, &j);

就可以了。

但是...(正如您同时评论的那样)

您注意到如果执行此操作,所有线程都会打印相同的数字。 发生这种情况是因为您将相同变量的相同地址传递给每个线程。 并且线程执行的时候没有特定的顺序。 很有可能在整个循环完成后执行第一个线程。 为避免这种情况,您必须为每个线程提供不同的值。 您不能通过仅向该函数调用添加参数来做到这一点。 相反,您必须为每个线程提供单独的内存。 您可以按如下方式执行此操作:

  int params[NUM_THREADS];
  for (j = 0; j < NUM_THREADS; j++)
  {
    params[j] = j;
    pthread_create(&tid[j], NULL, hello, &params[j]);
  }

这将导致每个线程打印不同的数字。

很简单,你把参数 j 的传递过于复杂了,你只需要使用 &

传递它的地址

语法是

int pthread_create(pthread_t *thread, pthread_attr_t *attr,
                   void *(*start_routine) (void *arg), void *arg);

传递给函数

void *thread(void *arg)

你的行应该是

pthread_create(&tid[j], NULL, hello, &j);

练习的预期输出

Hello World from branch thread 1
Hello World from branch thread 2
Hello World from branch thread 3
Hello World from branch thread 4