如果它保证满足以下所有条件,我需要检查解决餐饮哲学家问题的算法:
我在筷子上使用信号量来解决问题.
这是我的代码(算法):
while(true)
{
// He is Hungry
pickup_chopsticks(i);
// He is Eating...
drop_chopsticks(i);
// He is thinking
}
// ...
void pickup_chopsticks(int i)
{
if(i % 2 == 0) /* Even number: Left, then right */
{
semaphore_wait(chopstick[(i+1) % NUM_PHILOSOPHERS]);
semaphore_wait(chopstick[i]);
}
else /* Odd number: Right, then left */
{
semaphore_wait(chopstick[i]);
semaphore_wait(chopstick[(i+1) % NUM_PHILOSOPHERS]);
}
}
void drop_chopsticks(int i)
{
semaphore_signal(chopstick[i]);
semaphore_signal(chopstick[(i+1) % NUM_PHILOSOPHERS]);
}
Run Code Online (Sandbox Code Playgroud)
我相信这里不存在死锁的可能,但这里有可能出现饥饿问题吗?如果是,我该如何解决?
我被要求为python中的餐饮哲学家问题写一个简单的解决方案.这本身似乎很直接但是有些困惑,因为我被要求编写一个非阻塞解决方案.在这种情况下,我不确定这是什么意思.
有人能够提供任何提示或指出我正确的方向吗?
生产者/消费者和读者/作家很容易想到,但是餐饮哲学家呢?在什么样的情况下,N个进程和N个资源将位于环形拓扑上并相互交错?我可以想到N个进程争用M个资源,但是在这种情况下,每个进程都可以使用任何两个资源。
维基百科说Dijkstra用它来模拟竞争磁带机外围设备的计算机。这种情况在现代仍然存在吗?
我的MPI C程序有问题.这是代码:
void wantEat(int p, int rank, char *state, char* stateLeft, char* stateRight){
char *s;
MPI_Status status ;
/* if left or right neighbor is eating */
if(compare(stateLeft, "eat") || compare (stateRight, "eat")){
state = "want_Eat";
printf("%s : I wait for eating\n", nomPhilosophe(rank));
/* the process have to send his new state to his neighbors */
MPI_Send(state, strlen(state)+1, MPI_CHAR,
(rank - 1 + p) % p, 0, MPI_COMM_WORLD);
MPI_Send(state, strlen(state)+1, MPI_CHAR,
(rank + 1) % p, 0, MPI_COMM_WORLD);
/* if …Run Code Online (Sandbox Code Playgroud) 前段时间我使用 pthread 为 Dining Philosophers Problem 编写了一个 C 程序,现在我正在尝试将其更改为使用 fork() 代替。这是我已经通过的讲座的练习。但是一个朋友向我求助,我似乎无法自己弄清楚,这让我发疯!
如果我做一个“ps”,进程就在那里。但是标准输出没有任何输出,所以我认为我的管道有问题。
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define N 5
#define LEFT (i+4)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
sem_t spoon;
sem_t phil[N];
int state[N];
int phil_num[N]={0,1,2,3,4};
int fd[N][2]; // file descriptors for pipes
pid_t pid, pids[N]; // process ids
int i;
int num;
void philosopher(int i);
void test(int i);
void take_spoon(int i); …Run Code Online (Sandbox Code Playgroud) 我正在尝试,但是一个问题:在wiki中,该算法的第3点说:
当一个带叉子的哲学家接收到一条请求消息时,如果它是干净的话,他会保留它,但是当它是脏的时候放弃它.如果他把叉子送过来,他会在这之前清理叉子
我试图理解为什么这不会导致死锁?如果一个哲学家有一个干净的叉子,并等待从邻近的餐馆/哲学家那里获得另一个干净的叉子,而他们也在等待叉子,这可以累积到一个死锁对吗?一个哲学家总是在等待另一个人的分叉?
ps:我是线程和并发的新手,把它作为一个学习项目.
编辑:给出叉子的实际位置,张贴此以询问叉子是否应该是可变的.pLeft,pRight是左右哲学家,fLeft和fRight是左右分叉.
private Fork giveFork(Philosopher diner) {
Fork forkToGive;
if (this.pLeft.equals(diner)) {
// give left fork to left philosopher
if (this.fLeft.isClean)
forkToGive = null; // don't give
else {
forkToGive = new Fork(this.fLeft.id, true); // give the fork
}
} else if (diner.pRight.equals(this)) {
// give right fork to right philosopher
if (this.fRight.isClean)
forkToGive = null;
else {
forkToGive = new Fork(this.fRight.id, true);
}
} else {
// default value , i'm not yet sure …Run Code Online (Sandbox Code Playgroud) 我正在研究餐饮哲学家计划.然而,我遇到了一个问题,即我的程序在所有哲学家都吃过之前停止了,我不明白为什么.这是我现在的代码:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void *func(int n);
pthread_t philosopher[5];
pthread_mutex_t chopstick[5];
int main()
{
int i;
void *msg;
for(i=1;i<=5;i++)
{
pthread_mutex_init(&chopstick[i],NULL);
}
for(i=1;i<=5;i++)
{
pthread_create(&philosopher[i],NULL,(void *)func,(int *)i);
}
for(i=1;i<=5;i++)
{
pthread_join(philosopher[i],&msg);
}
for(i=1;i<=5;i++)
{
pthread_mutex_destroy(&chopstick[i]);
}
return 0;
}
void *func(int n)
{
printf ("\nPhilosopher %d is thinking ",n);
pthread_mutex_lock(&chopstick[n]);//when philosopher 5 is eating he takes fork 1 and fork 5
pthread_mutex_lock(&chopstick[(n+1)%5]);
printf ("\nPhilosopher %d is eating ",n);
sleep(3);
pthread_mutex_unlock(&chopstick[n]);
pthread_mutex_unlock(&chopstick[(n+1)%5]);
printf ("\nPhilosopher %d finished eating ",n);
}
Run Code Online (Sandbox Code Playgroud) 我已经为Dining Philosopher's Problem 实现了资源层次结构解决方案.当我尝试比较两个Chopsticks的n值时,它们最终陷入僵局.但是,如果我使用他们的hashCodes而不是n值,它会顺利运行.为何如此区别?这一天结束时他们都不是?
import java.util.Random;
class Chopstick {
public final int n;
public Chopstick(int n) {
this.n = n;
}
}
class Philosopher extends Thread {
private Chopstick left, right;
private Random random;
private final int n;
public Philosopher(int n, Chopstick left, Chopstick right) {
this.n = n;
if (left.n > right.n) { // no deadlock if I replace this with left.hashCode() > right.hashCode()
this.right = left;
this.left = right;
} else {
this.left = left;
this.right …Run Code Online (Sandbox Code Playgroud) 哲学家进餐问题是一个经典的计算机科学教科书问题,用于演示多线程的使用。正如维基百科所说:
五位沉默的哲学家端着一碗意大利面坐在圆桌旁。叉子放在每对相邻的哲学家之间。
每个哲学家都必须交替思考和进食。但是,哲学家只有在左叉和右叉同时拥有时才能吃意大利面。每个叉子只能由一个哲学家持有,因此只有当叉子没有被其他哲学家使用时,哲学家才能使用它。在一个哲学家吃完饭后,他们需要放下两个叉子,以便其他人可以使用这些叉子。哲学家只能在有可用的时候拿走他们右边或左边的叉子,并且在拿到两把叉子之前他们不能开始吃饭。
进食不受剩余意大利面条或胃空间的限制;假设无限供给和无限需求。
问题是如何设计行为准则(并发算法),使哲学家不会挨饿;即,每个人都可以永远继续在吃饭和思考之间交替,假设没有哲学家可以知道其他人什么时候想吃饭或思考。
该问题旨在说明避免死锁的挑战,死锁是一种不可能取得进展的系统状态。
总之,这是多线程中的一个经典问题,表明需要使用互斥原则来避免资源匮乏。
我想在实模式 DOS 中实现这样的程序,但是 DOS 显然缺乏多线程功能。
我知道第三方软件,例如RTKernel,但这对于这种情况似乎有点过分。
是否有任何模拟多线程的解决方案,以便我可以使用 16 位 x86 汇编语言在 DOS 中对哲学家进餐问题的模拟进行编程?
以下是我的餐饮哲学家代码,并产生一个编译错误说"'do'结构中的最后一个语句必须是一个表达式:mVar2 < - newEmptyMVar mVar3"有人可以帮我修复这个错误并让这个程序工作吗?谢谢
import Control.Concurrent
import Control.Concurrent.MVar
import System.Random
takefork :: Int -> forks -> IO ()
takefork n forks = takeMVar (forks!!n)
releasefork :: Int -> forks -> IO ()
releasefork n forks = putMVar (forks!!n)
philosopher :: [Int]
philosopher = [1,2,3,4,5]
forks :: [MVar] -> [Int]
forks = do
takefork n ( philosopher - 1)
threadDelay delay
let delay = 100000
takefork n philosopher
putStrLn("Philosopher" ++ philosopher ++ "has started eating")
releasefork n philosopher
releasefork n …Run Code Online (Sandbox Code Playgroud)