进程间信号量
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>
//sem_t用于进程间通信需要放到共享内存区
void *createSM(size_t size)//创建共享区
{
void *addr=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0);
if(addr==MAP_FAILED)
return NULL;
return addr;
}
void *freeSM(void* addr,size_t size)//释放共享区
{
if(munmap(addr,size)==-1)
printf("munmap(%p,%d) failed",addr,(int)size);
}
sem_t* forks[5];//五根筷子
sem_t* four;//拿叉子的资格,最多四人有资格
int main()
{
int i,times=2;
//创建共享区
for(i=0;i<5;i++)
{
forks[i]=createSM(sizeof(sem_t));
if(forks[i]==NULL)
{
printf("create shared memory failed\n");
exit(1);
}
}
four=createSM(sizeof(sem_t));
if(four==NULL)
{
printf("create shared memory failed\n");
exit(1);
}
//初始化信号量
for(i=0;i<5;i++)
{
int ret=sem_init(forks[i],1,1);
if(ret==-1)
{
fprintf(stderr,"%s\n",strerror(errno));
exit(-1);
}
}
int ret=sem_init(four,1,4);
if(ret==-1)
{
fprintf(stderr,"%s\n",strerror(errno));
exit(-1);
}
//创建五个进程
for(i=0;i<5;i++)
{
pid_t pid=fork();
if(pid==-1)
{
perror("fork");
exit(1);
}
else if(pid==0)
break;
}
//父进程
if(i==5)
{
int n=5;
while(n)
{
pid_t pid=waitpid(-1,NULL,WNOHANG);
if(pid>0)
{
n--;
printf("子进%d程已被回收\n",pid);
}
}
sleep(1);
}
//子进程
if(i<5)
{
while(times--)
{
printf("哲学家%d思考1秒...\n",i);
sleep(1);
//阻塞等待获得资格
sem_wait(four);
sem_wait(forks[i]);
sem_wait(forks[(i+1)%5]);//获得两根筷子
printf("哲学家%d开始吃饭...\n",i);
sleep(1);
printf("哲学家%d吃完了,开始释放资源...\n",i);
sem_post(forks[i]);
sem_post(forks[(i+1)%5]);
sem_post(four);
sleep(1);
}
}
//释放资源
for(i=0;i<5;i++)
{
freeSM(forks[i],sizeof(sem_t));
sem_destroy(forks[i]);
}
freeSM(four,sizeof(sem_t));
sem_destroy(forks[i]);
return 0;
}
进程间互斥量
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>
#include<pthread.h>
typedef struct
{
pthread_mutex_t mutex;
pthread_mutexattr_t mutexattr;
} mt;
int main()
{
int i;
mt* forks[5];
pid_t pid;
//创建匿名映射区
for(i=0;i<5;i++)
{
forks[i]=mmap(NULL,sizeof(mt),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
//memset(forks[i],0,sizeof(mt));
//初始化mutexattr
pthread_mutexattr_init(&forks[i]->mutexattr);
//修改属性为进程间共享
pthread_mutexattr_setpshared(&forks[i]->mutexattr,PTHREAD_PROCESS_SHARED);
//初始化锁
pthread_mutex_init(&forks[i]->mutex,&forks[i]->mutexattr);
}
//创建并初始化信号量
sem_t* four;
four=mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
sem_init(four,1,4);
//创建5个子进程
for(i=0;i<5;i++)
{
pid_t pid=fork();
if(pid==0)
break;
}
if(i==5)//父进程
{
int n=5;
while(n)
{
pid_t pid=waitpid(-1,NULL,WNOHANG);
if(pid>0)
{
n--;
printf("子进程%d已被回收\n",pid);
}
}
}
if(i<5)
{
int times=2;
while(times--)
{
printf("哲学家%d思考1秒...\n",i);
sleep(1);
//申请资源
sem_wait(four);
pthread_mutex_lock(&forks[i]->mutex);
pthread_mutex_lock(&forks[(i+1)%5]->mutex);
printf("哲学家%d开始吃饭...\n",i);
sleep(1);
//释放资源
pthread_mutex_unlock(&forks[i]->mutex);
pthread_mutex_unlock(&forks[(i+1)%5]->mutex);
sem_post(four);
printf("哲学家%d吃完了...\n",i);
}
}
for(i=0;i<5;i++)
{
pthread_mutexattr_destroy(&forks[i]->mutexattr);//销毁mutexattr
pthread_mutex_destroy(&forks[i]->mutex);//销毁mutex
munmap(forks[i],sizeof(mt));
}
sem_destroy(four);
munmap(four,sizeof(sem_t));
printf("哲学家们已经吃完饭...\n");
return 0;
}
线程间信号量
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>
#include<pthread.h>
sem_t forks[5],four;
void* eat(void* arg)
{
int i=(int)arg;
//printf("i=%d\n",i);
int times=2;
while(times--)
{
printf("哲学家%d开始思考1秒...\n",i);
sem_wait(&four);
sem_wait(&forks[i]);
sem_wait(&forks[(i+1)%5]);
printf("哲学家%d开始吃饭...\n",i);
sleep(1);
sem_post(&forks[i]);
sem_post(&forks[(i+1)%5]);
sem_post(&four);
printf("哲学家%d吃完了...\n",i);
sleep(1);
}
}
int main()
{
//初始化信号量
int i;
for(i=0;i<5;i++)
sem_init(&forks[i],0,1);
sem_init(&four,0,4);
//创建子线程
pthread_t pid[5];
for(i=0;i<5;i++)
pthread_create(&pid[i],NULL,eat,(void*)i);
//回收子线程
for(i=0;i<5;i++)
{
pthread_join(pid[i],NULL);
printf("------------子线程%d已被回收\n",i);
}
//销毁信号量
sem_destroy(&four);
for(i=0;i<5;i++)
sem_destroy(&forks[i]);
return 0;
}