Linux:睡眠理发师问题(用C语言实现)

Linux:睡眠理发师问题(用C语言实现),第1张

/*基于信号量采用多线程技术实现进程同步*/

#include <pthread.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <semaphore.h>

#include <sys/time.h>

#include <math.h>腔悄

#define CHAIRS 5 //椅子数

sem_t customers //等待服务的顾客信号量

sem_t barbers  //等待顾客的理发师信号量

pthread_mutex_t mutex //互斥变量

int waiting = 0 //正在等待的顾客数

void *barber(void *arg)

void *customer(void *num)

void cut_hair(void)

double timediff(struct timeval i,struct timeval j)

void seed_random(void)

double flat(void)

double normal(void)

double bursty(void)

int main()

{

   int i

   seed_random()

   pthread_t barber_t,customer_t

   int error

   error=pthread_create(&barber_t,NULL,barber,NULL)//创建理发师线程

   if(error!=0) {

      printf("pthread_create is not created.../n")

      return -1

   }

   while(1) {

      usleep(30000)//等待时间如果小于理发师理发时间则会出现等待者过多,否则不会出现等待者过多的现象

      error=pthread_create(&customer_t,NULL,customer,NULL)//创建顾客线程

      if(error!=0) {

         printf("pthread_create is not created.../n")

         return -1

      }

   }

}

double timediff(struct timeval now,struct timeval earlier)

{

   if(now.tv_sec == earlier.tv_sec)

      return (now.tv_usec - earlier.tv_usec)/1000000.0

   else

      return (1000000*(now.tv_sec - earlier.tv_sec) + now.tv_usec - earlier.tv_usec)/1000000.0

}

void *barber(void *arg)

{

   while(1)

   {

      sem_wait(&customers)//顾客信号量-1

      pthread_mutex_lock(&mutex)

      waiting = waiting -1

      sem_post(&barbers)//

      pthread_mutex_unlock(&mutex)

      cut_hair()//理发

   }

}

void cut_hair(void)

{

   printf("  Barber:I am cutting the customer's hair.../n")

   usleep(100000)//理发时间

   printf("  Barber:done./n")

}

void *customer(void *num)

{

   pthread_mutex_lock(&mutex)

   if(waiting<CHAIRS)

   {

   伍帆渣    waiting = waiting + 1

       sem_post(&customers)

       pthread_mutex_unlock(&mutex)

       sem_wait(&barbers) 

   }

   else

   {

      printf("  Waiter is too much.../n")

      pthread_mutex_unlock(&mutex)

   }

   //释放占用的轿稿资源

}

void seed_random(void)

{

   struct timeval randtime

   unsigned short xsub1[3]

   gettimeofday(&randtime,(struct timezone *)0)

   xsub1[0] = (ushort)randtime.tv_usec

   xsub1[1] = (ushort)(randtime.tv_usec >> 16)

   xsub1[2] = (ushort)(getpid())

   seed48(xsub1)

}

double flat()

{

   return drand48()/5

}

第二问 加个理发师忙碌数量 用来判断 即可

#include<sys/socket.h>裤碰 //提供socket数及数据结构

#include<string.h>

#include<unistd.h>

#include<signal.h>

#include<sys/ipc.h>

#include<errno.h>

#include<sys/shm.h>

#include<time.h>

#define PERM S_IRUSR|S_IWUSR

#define MYPORT 3490 #define BACKLOG 10

#define WELCOME "|----------Welcome to the chat room! ----------|" //宏定义,当客户端连接服务端时,想客户发送此欢迎字符串 //转换函数,将int类型转换芦纯知成char *类型

void itoa(int i,char*string) {

int power,j j=i

for(power=1j>=10j/=10) power*=10

for(power>0power/=10){

*string++='0'+i/power i%=power }

*string='\0'}

//得到当前系统时间

void get_cur_time(char * time_str) {

time_t timep

struct tm *p_curtime

char *time_tmp

time_tmp=(char *)malloc(2) memset(time_tmp,0,2)

memset(time_str,0,20) time(&timep)

p_curtime = localtime(&timep) strcat(time_str," (")

itoa(p_curtime->tm_hour,time_tmp) strcat(time_str,time_tmp) strcat(time_str,"陪消:")

itoa(p_curtime->tm_min,time_tmp) strcat(time_str,time_tmp) strcat(time_str,":")

itoa(p_curtime->tm_sec,time_tmp) strcat(time_str,time_tmp) strcat(time_str,")")

free(time_tmp)}

//创建共享存储区

key_t shm_create() {

key_t shmid

//shmid = shmget(IPC_PRIVATE,1024,PERM)

if((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1){

fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno)) exit(1) }

return shmid}

//端口绑定函数,创建套接字,并绑定到指定端口

int bindPort(unsigned short int port) {

int sockfd

struct sockaddr_in my_addr

sockfd = socket(AF_INET,SOCK_STREAM,0)//创建基于流套接字

my_addr.sin_family = AF_INET//IPv4协议族

my_addr.sin_port = htons(port)//端口转换

my_addr.sin_addr.s_addr = INADDR_ANY

bzero(&(my_addr.sin_zero),0)

if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1){

perror("bind")

exit(1) }

printf("bing success!\n")

return sockfd}

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

int sockfd,clientfd,sin_size,recvbytes//定义监听套接字、客户套接字

pid_t pid,ppid //定义父子线程标记变量

char *buf, *r_addr, *w_addr, *temp, *time_str//定义临时存储区

struct sockaddr_in their_addr //定义地址结构

key_t shmid

shmid = shm_create()//创建共享存储区

temp = (char *)malloc(255)

time_str=(char *)malloc(20)

sockfd = bindPort(MYPORT)//绑定端口

while(1){

if(listen(sockfd,BACKLOG) == -1)//在指定端口上监听 {

perror("listen")

exit(1) }

printf("listening......\n")

if((clientfd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)//接收客户端连接 {

perror("accept")

exit(1) }

printf("accept from:%d\n",inet_ntoa(their_addr.sin_addr))

send(clientfd,WELCOME,strlen(WELCOME),0)//发送问候信息

buf = (char *)malloc(255)

ppid = fork()//创建子进程

if(ppid == 0) {

//printf("ppid=0\n")

pid = fork() //创建子进程

while(1){

{

if(pid >0) {

memset(buf,0,255)

if (strcmp(str_1, “88”) == 0||strcmp(str_1, “byebye”) == 0|| strcmp(str_1, “拜拜”) == 0)

{

Exit(0)

}//当发言者发出类似“88”、“byebye”、“再见”等信息时,能自动结束进程。

if((recvbytes=recv(clientfd,buf,255,0))<=0) {

perror("recv1")

close(clientfd)

raise(SIGKILL)

exit(1)

}

w_addr = shmat(shmid, 0, 0)

memset(w_addr, '\0', 1024)

strncpy(w_addr, buf, 1024)

get_cur_time(time_str)

strcat(buf,time_str)

printf(" %s\n",buf)

}

else if(pid == 0)

{

sleep(1)

r_addr = shmat(shmid, 0, 0)

if(strcmp(temp,r_addr) != 0)

{

strcpy(temp,r_addr)

get_cur_time(time_str)

strcat(r_addr,time_str)

if(send(clientfd,r_addr,strlen(r_addr),0)==-1) {

perror("send")

}

memset(r_addr,'\0',1024)

strcpy(r_addr,temp)

}

}

else

perror("fork")

}

}

}

printf("------------------------------\n")

free(buf)

close(sockfd)

close(clientfd)

return 0

}

这个简单,你做1的时候不是应该已经用了一个计数信号量了吗(数有几个人等着),在2里你也用一个计数信号量数有几个空闲的理发师就颤旁可以了。

看起来没有问题,只要那个barber1的maximumCount等于2就可以了,这样就能有两个customer同时理发了,因为第一个p(barber)得到一个橡物barber,barber的计数下降为1,然后第二个p(barber)还梁洞液能再得到一次。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12509377.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存