【问题标题】:Spawning Arbitrary Number of Threads产生任意数量的线程
【发布时间】:2020-03-08 18:48:12
【问题描述】:

我正在尝试编写一个程序,它将产生任意数量的线程,类似于我在Convert a process based program into a thread based version? 中的代码,它使用进程来完成我想要完成的事情,到目前为止我有以下代码,我目前收到很多警告,但我真的想知道我是否正在接近我正在尝试做的事情。

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

void *runner(void *param); //the thread

int main(int argc, char *argv[]) {
  pthread_t tid = gettid();
  pthread_attr_t attr;

  if (argc != 2){
    fprintf(stderr, "Usage: a.out <integer value>\n");
    return -1;
  }

  if (atoi(argv[1]) < 0) {
    fprintf(stderr, "Argument %d must be non negative\n", atoi(argv[1]));
    return -1;
  }

  printf("My thread identifier is: %d\n", tid);

  // default attributes
  pthread_attr_init(&attr);

  // create the thread
  pthread_create(&tid, &attr, runner, argv[1]);

  // wait for the thread to exit
  pthread_join(tid, NULL);

}

void *runner(void *param){
  //int i, upper = atoi(param);
  int i;
  srand48(gettid());
  int max = nrand()%100;

  if (max > 0){
    for (i=1; i<=max; i++){
      printf("Child %d executes iteration\n", param, i);
    }
  }
  pthread_exit(0);
}

感谢我能得到的任何指导!

【问题讨论】:

  • 您似乎忘记了包含您希望我们解决的警告。
  • @ikegami 好吧,有很多......这让我相信我的语法是错误的,但我可以自己解决这个问题,我更担心代码不是为我想要做的事情工作,从逻辑上讲,我编写的代码应该正确地产生一些线程还是我错过了一些部分?
  • 关于:`pthread_t tid = gettid();` 这将返回 main() 函数的 TID,即 iffy,程序不感兴趣。
  • 关于; printf("Child %d executes iteration\n", param, i); 这是thread,而不是child process
  • thread id 是通过调用pthread_create()(第一个参数)生成的

标签: c multithreading process operating-system pthreads


【解决方案1】:

如果我理解您的目标,您希望创建命令行参数指示的线程数。

(请记住,任何特定的操作系统只能支持固定数量的线程,这取决于操作系统,所以我不会在这里验证这个数字的大小。)

以下建议的代码:

  1. 干净编译
  2. 执行所需的功能
  3. 记录包含每个头文件的原因
  4. 检查从 C 库函数返回的错误指示,例如 pthread_create()

现在建议的代码:

#include <stdio.h>   // printf(), perror(), NULL
#include <pthread.h> // pthread_create(), pthread_join(), pthread_t
#include <stdlib.h>  // exit(), EXIT_FAILURE, atof()

void *runner(void *param); //the thread

int main(int argc, char *argv[]) 
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <integer value>\n", argv[0]);
        exit( EXIT_FAILURE );
    }

    // might want to use: `strtol()` rather than `atoi()` 
    // so can check for errors
    size_t maxThreads = (size_t)atoi(argv[1]);

    pthread_t tid[ maxThreads ];   
    for( size_t i=0; i<maxThreads; i++ )
    {
        tid[i] = 0;
    }

    // create the threads
    for( size_t i=0; i<maxThreads; i++ )
    {
        if( pthread_create( &tid[i], NULL, runner, (void *)i ) )
        { 
            perror( "pthread_create failed" );
        }
    }

    // wait for each thread to exit
    for( size_t i = 0; i<maxThreads; i++ )
    {
        // if thread was created, then wait for it to exit
        if( tid[i] != 0 )
        {
            pthread_join( tid[i], NULL );
        }
    }
}


void *runner(void *arg)
{
    size_t threadNum = (size_t)arg;
    printf( "in thread: %zu\n", threadNum );

    pthread_exit( NULL );
}

没有命令行参数的运行会导致:(可执行文件的名称为:无标题

Usage: ./untitled <integer value>

命令行参数为 10 的运行结果:

in thread: 0
in thread: 4
in thread: 2
in thread: 6
in thread: 1
in thread: 5
in thread: 7
in thread: 8
in thread: 9
in thread: 3

这清楚地表明线程没有特定的顺序运行

【讨论】:

  • 非常感谢!我一直在试图弄清楚如何做到这一点并且未能理解(我对 C 编程还是很陌生),你说得非常清楚易懂,我真的很感谢你给我一些东西一起工作!
【解决方案2】:

1:我没有看到名为 gettid() 的函数

pthread_t tid = gettid();
srand48(gettid());

2:您不能将 pthread_t 打印为整数,它是一个结构体

printf("My thread identifier is: %d\n", tid);

3:是rand(),之前没见过nrand()。

int max = nrand()%100;

修复这些问题并根据需要编辑问题。

【讨论】:

  • 我已经编辑了问题,感谢您指出这些错误!我知道 getpid() 不适用于线程,我曾认为 gettid() 是 c 中的一个函数。我也觉得 rand() 不适合线程
  • 是的,rand 不安全,请改用 drand48_r 或 erand48
  • 好的,所以我已将使用 gettid() 的行替换为:“pthread_t tid = syscall(SYS_gettid);”以及使用 rand() 的行:“int max = drand48_r()%100;”这看起来是正确的方法吗?
  • 你不需要系统调用,对不起,我昨晚睡着了才正确回答,但@user3629249 是正确的。下一次编辑将是关于您在 main.js 中仅创建 1 个线程。请记住,您应该只从 main 创建线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
相关资源
最近更新 更多