私の問題は、このプログラムを Linux マシンと自分の Mac コンピューターで実行したときに発生するセグメンテーション違反に対処しています。このプログラムは、自分の Mac コンピューターでは正常に実行されますが、学校の Linux コンピューターで実行しようとすると、Mac コンピューターには表示されないセグメンテーション エラーが発生します。課題の背景を簡単に説明してから、問題を詳しく説明します。
だから私は基本的に一本のロープで峡谷を渡るヒヒをシミュレートするこのプログラムを持っています。一度に横断できるのは 1 匹のヒヒだけであり、一度に横断できるヒヒの数には一定の制限があります。また、別の方向からのヒヒが横断できるようになる前に、ある方向から横断できるヒヒの数にも一定の制限があります。コードの実装。
私はすでにここstackoverflowでセグメンテーション違反の質問を検索しましたが、それらのほとんどは複数のプロセスを扱っていますが、私は単に異なるスレッドを使用しています. セグメンテーション違反は、存在しないセマフォを待機することで発生しますが、初期化されているかどうかを確認したところ、正常に初期化されました。繰り返しますが、このプログラムは私の Mac では動作しますが、Mac で実行しようとすると動作しません。Linuxマシンでは実行できないが、Macでは実行できる理由を理解するのに役立ちます。さらに情報が必要な場合は、喜んで提供いたします。ある時点でエラー チェックを行いましたが、そのコードは学校のコンピューターから削除されました。私のエラーチェックでは、覚えている限り、エラーは表示されませんでした。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h> //for mode flags, if needed for future use
#define ATOB_COUNT 20
#define BTOA_COUNT 20
#define RANDOM_SEED 2123
//semaphore names
#define MUTEX_SEM "/mutex"
#define TOB_SEM "/toB"
#define TOA_SEM "/toA"
//define methods here if needed
void *toAThread(void *threadId);
void *toBThread(void *threadId);
void my_sleep(int limit);
void sem_open_errorCheck(char *name, unsigned int startingValue, sem_t *result);
//defining semaphores and shared variables
sem_t *mutex, *toB, *toA;
int xingCount = 0;
int xedCount = 0;
int toBWaitCount = 0;
int toAWaitCount = 0;
enum xingDirectionTypes {
none,
aToB,
bToA
};
enum xingDirectionTypes xingDirection = none;
char orderLeaving[100];
struct threadInfo {
int threadId;
};
struct threadInfo atobIDs[ATOB_COUNT];
struct threadInfo btoaIDs[BTOA_COUNT];
int main(void) {
pthread_t atobPTHREADS[ATOB_COUNT];
pthread_t btoaPTHREADS[BTOA_COUNT];
pthread_attr_t attr;
void *status;
srandom(RANDOM_SEED);
//call helper method which creates semaphore and errorchecks
sem_open_errorCheck(MUTEX_SEM, (unsigned int)1, mutex);
sem_open_errorCheck(TOA_SEM, (unsigned int)0, toA);
sem_open_errorCheck(TOB_SEM, (unsigned int)0, toB);
//Creating a set of attributes to send to the threads
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
//spawn toB baboons
int counter;
for (counter = 0; counter < BTOA_COUNT; counter++) {
atobIDs[counter].threadId = counter;
int result;
if ((result = pthread_create(&atobPTHREADS[counter], &attr, toBThread, (void*) &atobIDs[counter])) == -1) {
perror("Thread Creation Error: atob baboon");
exit(EXIT_FAILURE);
}
}
//spawn toA baboons
for (counter = 0; counter < ATOB_COUNT; counter++) {
btoaIDs[counter].threadId = counter + 20;
int result;
if ((result = pthread_create(&btoaPTHREADS[counter], &attr, toAThread, (void*) &btoaIDs[counter])) == -1) {
perror("Thread Creation Error: btoa baboon");
exit(EXIT_FAILURE);
}
}
//Wait for all the threads to finish
for(counter = 0; counter < ATOB_COUNT; counter++)
{
int result = pthread_join(atobPTHREADS[counter], &status);
if(result == -1)
{
perror("Thread Join: AtoB");
exit(EXIT_FAILURE);
}
}
for(counter = 0; counter < BTOA_COUNT; counter++)
{
int result = pthread_join(btoaPTHREADS[counter], &status);
if(result == -1)
{
perror("Thread Join: BtoA");
exit(EXIT_FAILURE);
}
}
printf("The order leaving %s", orderLeaving);
exit(EXIT_SUCCESS);
}
void *toBThread(void *threadId) {
struct threadInfo *info;
info = (struct threadInfo *)threadId;
int id = info->threadId;
my_sleep(100); //simulate being idle for 1-100ms
//for order checking
char *baboonOrder;
baboonOrder = "B ";
strcat(orderLeaving, baboonOrder);
sem_wait(mutex);
if ((xingDirection == aToB || xingDirection == none) && xingCount < 5 && (xedCount + xingCount) < 10) { //there is an extra parenthesis here in the solutions
xingDirection = aToB;
xingCount++;
printf("AtoB baboon (thread %d) got on the rope\n", id);
sem_post(mutex);
}
else {
toBWaitCount++;
sem_post(mutex);
sem_wait(toB);
toBWaitCount--;
xingCount++;
xingDirection = aToB;
printf("AtoB baboon (thread %d) got on the rope\n", id);
sem_post(mutex);
}
//CROSSING
sem_wait(mutex);
printf("AtoB baboon (thread %d) got off the rope\n", id);
xedCount++;
xingCount--;
if (toBWaitCount != 0 && (((xedCount+xingCount)<10) || ((xedCount+xingCount) >= 10 && toAWaitCount == 0))) {
sem_post(toB);
}
else {
if (xingCount == 0 && toAWaitCount != 0 && (toBWaitCount == 0 || (xedCount + xingCount)>=10)) {
xingDirection = bToA;
xedCount = 0;
sem_post(toA);
}
else {
if (xingCount == 0 && toBWaitCount == 0 && toAWaitCount == 0) {
xingDirection = none;
xedCount = 0;
sem_post(mutex);
}
else {
sem_post(mutex);
}
}
}
}
/*
baboons going from side a to side b
*/
void *toAThread(void *threadId) {
struct threadInfo *info;
info = (struct threadInfo *)threadId;
int id = info->threadId;
my_sleep(100);
//for order checking
char *baboonOrder;
baboonOrder = "A ";
strcat(orderLeaving, baboonOrder);
sem_wait(mutex);
if ((xingDirection == bToA || xingDirection == none) && xingCount < 5 && (xedCount + xingCount) < 10) { //there is an extra parenthesis here in the solutions
xingDirection = bToA;
xingCount++;
printf("BtoA baboon (thread %d) got on the rope\n", id);
sem_post(mutex);
}
else {
toAWaitCount++;
sem_post(mutex);
sem_wait(toA);
toAWaitCount--;
xingCount++;
xingDirection = bToA;
printf("BtoA baboon (thread %d) got on the rope\n", id);
sem_post(mutex);
}
//CROSSING
sem_wait(mutex);
printf("BtoA baboon (thread %d) got off the rope\n", id);
xedCount++;
xingCount--;
if (toAWaitCount != 0 && (((xedCount+xingCount)<10) || ((xedCount+xingCount) >= 10 && toBWaitCount == 0))) {
sem_post(toA);
}
else {
if (xingCount == 0 && toBWaitCount != 0 && (toAWaitCount == 0 || (xedCount + xingCount)>=10)) {
xingDirection = aToB;
xedCount = 0;
sem_post(toB);
}
else {
if (xingCount == 0 && toAWaitCount == 0 && toBWaitCount == 0) {
xingDirection = none;
xedCount = 0;
sem_post(mutex);
}
else {
sem_post(mutex);
}
}
}
}
//taken with permission from readers/writers problem
//Puts the calling thread to sleep to simulate both random start times and random workloads
void my_sleep(int limit) {
struct timespec time_ns;
int duration = random() % limit + 1;
time_ns.tv_sec = 0;
time_ns.tv_nsec = duration * 1000000;
int result = nanosleep(&time_ns, NULL);
if (result != 0)
{
perror("Nanosleep");
exit(EXIT_FAILURE);
}
}
void sem_open_errorCheck(char *name, unsigned int startingValue, sem_t *result) {
sem_unlink(name);
result = sem_open(name, O_CREAT, 0600, startingValue);
if (result == -1) {
perror("sem_open error: semaphore failed to open correctly");
exit(EXIT_FAILURE);
}
}