gpt4 book ai didi

c - 使用 POSIX 线程 : Program hangs every fourth or fifth run, 但在其他方面似乎可以工作

转载 作者:行者123 更新时间:2023-11-30 18:28:29 24 4
gpt4 key购买 nike

我有一个必须编写的 C 程序来创建 4 个线程。这 4 个“海盗”线程应该从“洞穴”中获取 1000 颗珍珠(值(value) 1000 的双倍珍珠),从“洞穴”中获取 10% 或 15%。他们一次只能去一个,当珍珠洞空了时,计划就会停止。该程序似乎运行正常,但在运行几次可执行文件后挂起。

为什么会发生这种情况?

代码:

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

#define NUM_PIRATE_THREADS 4
#define OPEN_SESAME 0
#define OPEN_WATERMELON 1

/* array of threads */
static pthread_t *thread_handles;

/* mutual exlusion lock; mutual exclusion considered in this version */
pthread_mutex_t mutex;

/* pirate thread function */
void *pirate(void* rank);

/* total number of items in resource (pearls in the cave) */
static double cavePearls = 1000.00;

/* amount of pearls pirate thread may take */
static double pearlsToGrab;

/* array to store the number of pearls garnered by each pirate */
int piratesBooty[NUM_PIRATE_THREADS];

/* main function */
int main() {

/* variable to loop through threads and output pearl consumption */
long threadIndex;

/* thread variable */
long currentThread;

/* initialize thread_handles array */
thread_handles = (pthread_t*)malloc(NUM_PIRATE_THREADS*sizeof(pthread_t));

/* create pirate threads...ARGGG!*/
for (currentThread = 0; currentThread < NUM_PIRATE_THREADS; ++currentThread) {
pthread_create(&thread_handles[currentThread], NULL, (void *(*)(void *))pirate, (void*)currentThread);
}

/* join pirate threads...ARGGG!*/
for (currentThread = 0; currentThread < NUM_PIRATE_THREADS; ++currentThread) {
pthread_join(thread_handles[currentThread], NULL);
}

/* update your final cave pearl number to a whole integer value */
cavePearls = ceil(cavePearls);

/* display pearl data after thread(s) execution */
printf("\nPearls left in cave: %d\n", (int)cavePearls);
for (threadIndex = 0; threadIndex < NUM_PIRATE_THREADS; ++threadIndex){
printf("Pirate %ld: %d pearls\n", threadIndex, piratesBooty[threadIndex]);
}

/* free memory */
free(thread_handles);

return 0;
}

void *pirate(void* rank) {

while(1) { /* continue execution as long as there are still pearls in the cave */
if (cavePearls == 0) /* cave has been emptied, pirates should stop */
return 0;

/* identify which pirate thread you are executing */
long my_rank = (long)rank;

/* CRITICAL SECTION LOCKED */
pthread_mutex_lock(&mutex);

if (cavePearls) {
if (my_rank % 2 == OPEN_SESAME) { /* if thread is 0 or 2: "Open, sesame" pirate */
pearlsToGrab = cavePearls * 0.10; /* "open sesame" = 10% of pearls removed */
pearlsToGrab = ceil(pearlsToGrab); /* get the ceiling if not an integer value */
cavePearls = cavePearls - pearlsToGrab; /* update the number of pearls in cave */
piratesBooty[my_rank] += pearlsToGrab; /* update pirate thread total pearls taken */

}
else if (my_rank % 2 == OPEN_WATERMELON){ /* if thread is 1 or 3: "Open, watermelon" pirate */
pearlsToGrab = cavePearls * 0.15; /* "open watermelon" = 15% of pearls removed */
pearlsToGrab = ceil(pearlsToGrab); /* get the ceiling if not an integer value */
cavePearls = cavePearls - pearlsToGrab; /* update the number of pearls in cave */
piratesBooty[my_rank] += pearlsToGrab; /* update pirate thread total pearls taken */
}
} /* end of while-loop */

/* CRITICAL SECTION UNLOCKED */
pthread_mutex_unlock(&mutex);

/* DEBUG SCRIPT
printf("I am thread %ld, I have %d pearls, I'm taking %d pearls, and \nthere are %d pearls left"
"in the cave.\n\n", my_rank, piratesBooty[my_rank], (int)pearlsToGrab, (int)cavePearls);
*/

}
/* have thread(s) terminate */
pthread_exit((void*)0);
}

一切看起来都很好!做了一些改变,事情看起来不错。如果您发现任何错误,请随时告诉我!

代码:

/*******************************************************************************
*******************************************************************************
Course: Operating Systems
Student: Douglas Adolph
Project: 3, Part 2

-------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
IMPORTANT NOTE:
///////////////////////////////////////////////////////////////////////////////
Some of this code borrows directly from material provided by Dr. Burtscher
in Texas State University's Parallel Programming course, as well as material
written by the author (Douglas Adolph) for said parallel programming course.
///////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
SUMMARY:
///////////////////////////////////////////////////////////////////////////////
Program illustrates use of threads and mutual exclusion. N "pirates" (threads)
complete for 1000 pearls in a cave. Passwords are used to be granted a certain
percentage of the remaining pearls in the cave. Program should terminate when
all the pearls have been taken.
///////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
PART 1 AND 2 SPECIFICS:
///////////////////////////////////////////////////////////////////////////////
Part 1: implementation with mutual exclusion NOT considered*
Part 2: implementation with mutual exclusion considered

*designed to fail during repeated runtime tests: demonstrate need for exclusion
*sleep() not used
///////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
THREAD ID, THREAD PASSWORD, AND RESOURCE (PEARLS) RETRIEVAL INFORMATION:
///////////////////////////////////////////////////////////////////////////////
Pirate threads ID'd by rank (i.e. 0, 1, 2, ...), and this rank is used to ID
which password pirate thread will use. However, in the program output, pirate
threads are labeled alphanumerically (i.e. A, B, C, ...). However, although
pirate threads in output are labeled alphanumerically to match professor's
example, some liberty was taken in the final design of the output.

Note: if there are more than 26 pirate threads, the implementation of the output
of total pearls gathered by all pirate threads will need to be changed, or
labels for all pirate threads after Z will not have reasonable labels

"Open, sesame:" N/2 pirate processes use this password and
receive 10% of the remaining pearls

"Open, watermelon:" N/2 pirate processes use this password and
receive 15% of the remaining pearls

Even-numbered pirate threads will be assigned password "Open, sesame," where
password string is represented by 1 (*)

Odd-numbered pirate threads will be assigned password "Open, watermelon," where
password string is represented by 0 (*)

(*) via a modulus operation (thread % 2); string PWs/buffers avoided
///////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
NOTES REGARDING TRANSFER AND EXECUTION OF FILE ON TEXAS STATE SERVERS:
///////////////////////////////////////////////////////////////////////////////

(1) transfer to Zeus for testing effected via:

scp /Users/douglasadolph/Desktop/School/CourseFolders/OperatingSystems/Projects
/YourProjects/project3_DouglasAdolph/FILE_NAME da1140@zeus.cs.txstate.edu:

(2) program compiled via:

gcc p3_part1_DouglasAdolph.c -o p3p1 -lpthread -lm
gcc p3_part2_DouglasAdolph.c -o p3p2 -lpthread -lm
///////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------
*******************************************************************************
******************************************************************************/

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

#define NUM_PIRATE_THREADS 4 /* number of pirate threads to run */
#define OPEN_SESAME 0 /* single bit value representation of password */
#define OPEN_WATERMELON 1 /* single bit value representation of password */

/* percent value for "open, sesame" */
const double OPEN_SESAME_PERCENTAGE = 0.10;

/* percent value for "open, watermelon" */
const double OPEN_WATERMELON_PERCENTAGE = 0.15;

/* array of pirate threads */
static pthread_t *thread_handles;

/* mutual exlusion lock; mutual exclusion considered in this version */
pthread_mutex_t mutex;

/* pirate thread function */
void *pirate(void* rank);

/* total number of items in resource (pearls in the cave) */
static double cavePearls = 1000.00;

/* array to store the number of pearls garnered by each pirate */
int piratesBooty[NUM_PIRATE_THREADS];

/* main function */
int main() {

/* alert user pirate threads are about to begin consuming pearls */
printf("\nAvast matey, we are a'comin' fer yee pearls!!\n\n");

/* index variable for pirate threads */
long threadIndex;

/* char variable for pirate thread labeling (i.e. 1, 2, 3, ...) */
char alphaForPirate = 'A';

/* create and allocate memory for thread_handles array */
thread_handles = (pthread_t*)malloc(NUM_PIRATE_THREADS*sizeof(pthread_t));

/* create and run pirate threads...YAR!*/
for (threadIndex = 0; threadIndex < NUM_PIRATE_THREADS; ++threadIndex) {
pthread_create(&thread_handles[threadIndex], NULL,
pirate, (void*)threadIndex);
}

/* join pirate threads...AVAST MATEY!*/
for (threadIndex = 0; threadIndex < NUM_PIRATE_THREADS; ++threadIndex) {
pthread_join(thread_handles[threadIndex], NULL);
}

/* update your final cave pearl number to a whole integer value */
cavePearls = ceil(cavePearls);

/* display pearl data after pirate thread(s) execution */
printf("\nYar!! The cave be empty!!\n\n");
for (threadIndex = 0; threadIndex < NUM_PIRATE_THREADS; ++threadIndex){
printf("Pirate %c got %d pearls\n",
alphaForPirate, piratesBooty[threadIndex]);
alphaForPirate++;
}
printf("\n");

/* free memory */
free(thread_handles);

return 0;
} /* end of main() */

void *pirate(void* rank) {

/* amount of pearls pirate thread(s) may take during current entry to cave */
static double pearlsToGrab = 0;

/* variables to output pirate thread(s) pearl consumption */
char alphaForPirate = 'A';
int piratePercentage;

/* label pirate thread(s) alphanumerically */
alphaForPirate += (long)rank;

while(1) { /* continue execution while pearls remain in cave */
if (cavePearls < 1) /* cave has been emptied, pirate thread(s) should stop */
return 0;

/* identify which pirate thread you are currently executing */
long my_rank = (long)rank;

/* if pirate thread is even: "Open, sesame" pirate */
if (my_rank % 2 == OPEN_SESAME) {

/* CRITICAL SECTION LOCKED */
pthread_mutex_lock(&mutex);

piratePercentage = (OPEN_SESAME_PERCENTAGE * 100);
pearlsToGrab = cavePearls * OPEN_SESAME_PERCENTAGE;
pearlsToGrab = ceil(pearlsToGrab);
cavePearls = cavePearls - pearlsToGrab;
piratesBooty[my_rank] += pearlsToGrab;

printf("Pirate %c gets %.0f of the pearls, %d percent of %.0f pearls available in cave\n",
alphaForPirate, pearlsToGrab, piratePercentage, (cavePearls + pearlsToGrab));

/* CRITICAL SECTION UNLOCKED */
pthread_mutex_unlock(&mutex);
}
/* if pirate thread is odd: "Open, watermelon" pirate */
else if (my_rank % 2 == OPEN_WATERMELON){

/* CRITICAL SECTION LOCKED */
pthread_mutex_lock(&mutex);

piratePercentage = (OPEN_WATERMELON_PERCENTAGE * 100);
pearlsToGrab = cavePearls * OPEN_WATERMELON_PERCENTAGE;
pearlsToGrab = ceil(pearlsToGrab);
cavePearls = cavePearls - pearlsToGrab;
piratesBooty[my_rank] += pearlsToGrab;

printf("Pirate %c gets %.0f of the pearls, %d percent of %.0f pearls available in cave\n",
alphaForPirate, pearlsToGrab, piratePercentage, (cavePearls + pearlsToGrab));

/* CRITICAL SECTION UNLOCKED */
pthread_mutex_unlock(&mutex);
}

/* make pirate thread(s) sleep for 2 seconds */
sleep(2);

} /* end of while-loop */

/* have pirate thread(s) terminate */
pthread_exit((void*)0);
}

最佳答案

在调试器中运行它,直到它挂起,然后中断它并查看状态。我怀疑对于某些执行,cavePearls 会变为负值,并且您的线程会继续运行。 if (cavePearls == 0) 应为“if (cavePearls <= 0)”。

关于c - 使用 POSIX 线程 : Program hangs every fourth or fifth run, 但在其他方面似乎可以工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46967213/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com