首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用线程生成随机数

使用线程生成随机数
EN

Stack Overflow用户
提问于 2020-11-17 06:38:31
回答 1查看 95关注 0票数 0

我尝试生成一个介于-1和+1之间的随机浮点数,总数由用户指定,以及线程的数量,然后随机数的总量在线程之间平均分配,线程都使用一个工作区结构。

代码语言:javascript
运行
复制
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

typedef struct WorkspaceStruct {
    unsigned int tid;
    int points_generated;
    int points_in_circle;
    unsigned int seed;
}Workspace;

void *worker(void *ws) {
    Workspace *workspace = (Workspace *) ws;  // link worker to workspace

    pthread_mutex_lock(&mutex);

    printf("Worker %d\n", workspace->tid);
    int max = workspace->points_generated;
    unsigned int seed = workspace->seed;
    for (int i = 0; i < max; ++i) {
        float point_x = (float)rand_r(&seed) / RAND_MAX * 2.0 - 1.0;
        float point_y = (float)rand_r(&seed) / RAND_MAX * 2.0 - 1.0;

        printf("x: %f, y: %f\n", point_x, point_y);
    }
    pthread_mutex_unlock(&mutex);

    pthread_exit(NULL);
}

void calculate_circle_area(int total_samples, int no_workers) {
    pthread_t worker_thread[no_workers];
    Workspace workspace;
    workspace.points_generated = total_samples / no_workers;
    workspace.tid = 0;
    workspace.seed = time(0);

    for (int i = 0; i < no_workers; ++i) {
        workspace.tid += 1;
        pthread_create(&worker_thread[i], NULL, worker, &workspace);
        pthread_join(worker_thread[i], NULL);
    }
}

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("usage: ./program [no. of samples] [no. of worker threads]\n");
        return EXIT_FAILURE;
    } else {
        int total_samples = atoi(argv[1]);
        int no_workers = atoi(argv[2]);

        printf("\n");
        calculate_circle_area(total_samples, no_workers);

        printf("\n");
        return EXIT_SUCCESS;
    }
}

这在很大程度上是有效的,它确实生成了随机数,并且一切都被正确地拆分,但是每个线程生成相同的数,但是线程中的每个数是不同的。

命令的输出示例:./calc_area 9 3(总共生成9个随机数,使用3个线程)

代码语言:javascript
运行
复制
Worker 1
x: 0.506291, y: -0.765927
x: -0.941786, y: -0.598265
x: 0.962658, y: -0.609824
Worker 2
x: 0.506291, y: -0.765927
x: -0.941786, y: -0.598265
x: 0.962658, y: -0.609824
Worker 3
x: 0.506291, y: -0.765927
x: -0.941786, y: -0.598265
x: 0.962658, y: -0.609824

我想让每个线程相互生成不同的数字,我该怎么做呢?谢谢

EN

回答 1

Stack Overflow用户

发布于 2020-11-17 08:14:54

由于您包含了多线程标记,因此这里有一个使用Ada的解决方案。在这种情况下,随机数种子由每个任务(即线程)重置,确保种子不同,因此随机数序列也不同。

代码语言:javascript
运行
复制
with Ada.Text_IO;               use Ada.Text_IO;
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
with Ada.Float_Text_IO;         use Ada.Float_Text_IO;
with Ada.Integer_Text_IO;       use Ada.Integer_Text_IO;

procedure Main is
   type Point is record
      X : Float;
      Y : Float;
   end record;

   procedure Print (Item : Point) is
   begin
      Put ("X:");
      Put (Item => Item.X, Fore => 2, Aft => 4, Exp => 0);
      Put (" Y:");
      Put (Item => Item.Y, Fore => 2, Aft => 4, Exp => 0);
      New_Line;
   end Print;

   type Point_Array is array (Positive range <>) of Point;

   task type worker is
      entry Set_Num (Count : Positive);
      entry Report;
   end worker;

   task body worker is

      Seed       : Generator;
      Num_Points : Positive;
   begin
      Reset (Seed);
      accept Set_Num (Count : Positive) do
         Num_Points := Count;
      end Set_Num;

      declare
         Buf : Point_Array (1 .. Num_Points);
      begin

         for I in Buf'Range loop
            Buf (I).X := Random (Seed) * 2.0 - 1.0;
            Buf (I).Y := Random (Seed) * 2.0 - 1.0;
         end loop;
         accept Report;
         for I in Buf'Range loop
            Print (Buf (I));
         end loop;
         New_Line;
      end;

   end worker;

   type Team is array (Positive range <>) of worker;
   Num_Tasks : Positive;
   Num_Rand  : Positive;

begin
   Put ("Enter the number of task: ");
   Get (Num_Tasks);
   Put ("Enter the number of results per task: ");
   Get (Num_Rand);
   declare
      Workers : Team (1 .. Num_Tasks);
   begin
      for I in Workers'Range loop
         Workers (I).Set_Num (Num_Rand);
      end loop;
      for I in Workers'range loop
         Put_Line ("Worker" & I'Image);
         Workers (I).Report;
         delay 0.01;
      end loop;
   end;

end Main;

使用6个任务和每个任务4个结果的执行的输出为:

代码语言:javascript
运行
复制
Enter the number of task: 6
Enter the number of results per task: 4
Worker 1
X: 0.7487 Y:-0.6497
X:-0.9634 Y: 0.6317
X:-0.9189 Y: 0.8070
X: 0.8837 Y:-0.3839

Worker 2
X: 0.6409 Y:-0.4913
X:-0.0185 Y: 0.1078
X:-0.6408 Y:-0.9719
X:-0.6199 Y: 0.9301

Worker 3
X:-0.9440 Y: 0.1089
X:-0.1354 Y:-0.3133
X: 0.8479 Y:-0.7389
X: 0.8399 Y: 0.4826

Worker 4
X:-0.9165 Y:-0.3652
X: 0.4137 Y:-0.6292
X: 0.6467 Y: 0.9344
X: 0.2898 Y: 0.1059

Worker 5
X: 0.8818 Y:-0.3551
X:-0.5161 Y:-0.5251
X:-0.6831 Y:-0.0531
X: 0.8207 Y:-0.7419

Worker 6
X: 0.2529 Y:-0.9385
X: 0.5640 Y: 0.3365
X:-0.4477 Y: 0.1642
X: 0.8230 Y: 0.8284
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64866748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档