C语言 在我的数字生成游戏中,我无法等待所有线程发送他们的数字



我用C语言编写这个程序,在每一轮中,每个线程生成一个从0到99的随机数,生成随机数最高的线程得一分,在所有回合结束时,得分最高的线程获胜。

我有麻烦弄清楚如何等待线程发送所有的数字。生成的随机数数组最初都是-1,我尝试使用while循环等待,直到没有-1剩余,但这给了我一个无限循环,而我应该继续寻找生成的最大数字并相应地分配点。

(这是我第一次使用线程,这是一个操作系统类)

#define HAVE_STRUCT_TIMESPEC
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#include<pthread.h>
#include<stdio.h>
#include<time.h>
//store random numbers generated by thread
int* randnums;
//shows whether a thread won or lost
int* res;
// signal for threads to send numbers in
int ready = 0;
//store the score(which is the number of wins for each thread
int* numwins;
//check if there is a -1 in the array
int containsnegative(int* a) {
int n = sizeof(a) / sizeof(a[0]);
n = (int)n;
for (int i = 0; i < n; i++) {
if (a[i] == -1) {
return 1;
}
}
return 0;
}

void* mythreadfunc(void* toread); 

int main(int argc, char* argv[]) {
//int i;

pthread_attr_t attr;
//get number of threads and number of rounds in the game
int numthreads; 
numthreads = atoi(argv[1]);
int numrounds = atoi(argv[2]);
srand(time(NULL));
int threadstocreate = numthreads;
//pthread_t tid;
pthread_t* threads;

threads = malloc(numthreads * sizeof(pthread_t));
randnums = (int*)malloc(sizeof(int) * numthreads);
res = (int*)malloc(sizeof(int) * numthreads);
numwins = (int*)calloc(numthreads, sizeof(int));
size_t randsize = sizeof(randnums) / sizeof(randnums[0]);
randsize = (int)randsize;
for (int x = 0; x < randsize; x++) {
randnums[x] = -1;
}
if (res == NULL) {
printf("res is null n");
}

//set all values in res array to 0. this will be changed to 1 if that thread wins
for (int k = 0; k < numthreads; k++) {
res[k] = 0; 
}

pthread_attr_init(&attr);
for (int i = 0; i < numthreads; i++) {
pthread_create(&(threads[i]), &attr, mythreadfunc, (void*)&i);
printf("thread createdn");
}

for (int k = 0; k < numrounds; k++) {
printf("round %d has startedn", k + 1);
ready = 1;
// wait for threads to send score in (This is where I am having my error)
while (containsnegative(randnums) == 1) {

}
//find max score
int max = 0;
for (int i = 0; i < numthreads; i++) {
if (randnums[i] > max) {
max = randnums[i];
}
}
//update score for all threads that scored the maximum
for (int i = 0; i < numthreads; i++) {
if (randnums[i] == max) {
numwins[i]++;
printf("Thread %d scored in this round!n", i + 1);
}
}
//reset randnums back to -1 for the next round
for (int i = 0; i < numthreads; i++) {
randnums[i] = -1;
}
//if we are in the last round then print the scores for all of the threads
if (k == numrounds - 1) {
for (int i = 0; i < numthreads; i++) {
printf("Thread %d scored %d pointsn",i+1,numwins[i]);
}
}


}
//pthread_join()
printf("Program Finishedn");
}

void* mythreadfunc(void* toread) {
// get where to send numbers
int whereToPut = *((int*)toread);
// if ready to send the numbers in send it in.
if (ready == 1) {
int numgenerated = rand() % 100;
printf("%dn", numgenerated);
printf("n");
randnums[whereToPut] = numgenerated;
printf("%dn", randnums[whereToPut]);
pthread_exit(0);
}
}

感谢您的一个有趣的多线程问题。下面的解决方案是用Ada编程语言编写的。Ada任务被映射到操作系统线程,但在裸机系统中,任务由Ada运行时管理。任务项允许在任务之间直接传递消息。在本例中,主线程调用Set_Limits条目来设置每个任务的ID和迭代次数。Go条目允许在每个任务中对随机数生成循环进行另一次迭代。每个任务将在accept语句处等待一个条目,直到另一个任务调用该任务的相应条目。任务项实现Ada Rendevous逻辑,强制任务之间的同步点。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Main is
subtype elements is Integer range 1 .. 40;
Max_Iterations : constant := 20;
type Buffs is array (elements) of Natural;
Buffers : Buffs;
task type Player is
entry Set_Limits (Id : in Positive; Count : in Positive);
entry Go;
end Player;
task body Player is
subtype values is Integer range 1 .. 100;
package rands is new Ada.Numerics.Discrete_Random (values);
use rands;
Seed     : Generator;
task_id  : Positive;
Num_Iter : Positive;
begin
Reset (Seed);
-- suspend until the Set_Limits entry is called
accept Set_Limits (Id : in Positive; Count : in Positive) do
task_id  := Id;
Num_Iter := Count;
end Set_Limits;
for I in 1 .. Num_Iter loop
-- suspend until the Go entry is called
accept Go;
Buffers (task_id) := Random (Seed);
end loop;
end Player;
-- create an array of Player tasks. They start immediately.
players : array (elements) of Player;
min_id  : elements;
min_val : Natural;
max_id  : elements;
max_val : Natural;
begin
-- initialize the players
for I in players'Range loop
players (I).Set_Limits (I, Max_Iterations);
end loop;
-- run game
for I in 1 .. Max_Iterations loop
-- zero the values in Buffers then get rand nums
Buffers := (others => 0);
-- call the go entry for each task
for I in players'Range loop
players (I).Go;
end loop;
delay 0.000_1; -- wait 0.1 milliseconds
min_id  := Buffers'First;
min_val := Buffers (Buffers'First);
max_id  := Buffers'First;
max_val := Buffers (Buffers'First);
-- find min and max values randomly generated
for I in Buffers'Range loop
if Buffers (I) < min_val then
min_val := Buffers (I);
min_id  := I;
end if;
if Buffers (I) > max_val then
max_val := Buffers (I);
max_id  := I;
end if;
end loop;
-- output the max and min values
Put_Line ("Max Id :" & max_id'Image & " Max value :" & max_val'Image);
Put_Line ("Min Id :" & min_id'Image & " Min value :" & min_val'Image);
Put_Line ("-------------");
end loop;
end Main;

程序的示例输出为:

Max Id : 1 Max value : 97
Min Id : 16 Min value : 3
-------------
Max Id : 2 Max value : 96
Min Id : 40 Min value : 2
-------------
Max Id : 2 Max value : 100
Min Id : 11 Min value : 1
-------------
Max Id : 34 Max value : 99
Min Id : 13 Min value : 4
-------------
Max Id : 30 Max value : 99
Min Id : 24 Min value : 3
-------------
Max Id : 22 Max value : 100
Min Id : 35 Min value : 1
-------------
Max Id : 3 Max value : 99
Min Id : 27 Min value : 2
-------------
Max Id : 33 Max value : 98
Min Id : 15 Min value : 3
-------------
Max Id : 16 Max value : 99
Min Id : 5 Min value : 5
-------------
Max Id : 35 Max value : 95
Min Id : 14 Min value : 3
-------------
Max Id : 5 Max value : 90
Min Id : 40 Min value : 1
-------------
Max Id : 4 Max value : 100
Min Id : 20 Min value : 3
-------------
Max Id : 9 Max value : 99
Min Id : 18 Min value : 4
-------------
Max Id : 5 Max value : 100
Min Id : 26 Min value : 2
-------------
Max Id : 26 Max value : 97
Min Id : 36 Min value : 3
-------------
Max Id : 2 Max value : 99
Min Id : 36 Min value : 1
-------------
Max Id : 33 Max value : 98
Min Id : 28 Min value : 7
-------------
Max Id : 3 Max value : 100
Min Id : 28 Min value : 1
-------------
Max Id : 5 Max value : 97
Min Id : 39 Min value : 1
-------------
Max Id : 4 Max value : 99
Min Id : 3 Min value : 4
-------------

最新更新