#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)还梁洞液能再得到一次。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)