求高手给点思路——信号量问题

cocat 2010-06-08 04:56:53
题目:
假设你开了家租船公司,你公司有10艘游艇可以提供给客户。请编写程序来模拟船公司和客户。如果有大于10个客户同时想向船公司租船,那么必须等待。

我的思路:
先fork然后子进程作为客户端程序(客户),父进程作为服务器程序(租船公司),但是具体不懂怎么写~请高手指点下~


#include <stdio.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <fcntl.h>

int semid; //全局变量
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};

int sem_p(void);
int sem_v(void);
int sem_init(void);
void sem_del(void);

int main(int argc, char *argv[])
{
pid_t pid;
pid = fork();

if (pid == -1)
{
perror("fork");
exit(-1);
}
else if (pid == 0) //child process
{

}
else //parent process
{
}
return 0;
}

int sem_init(void) //信号量初始化
{
union semun sem;
sem.val = 10;

if (semctl(semid, 0, SETVAL, sem) == -1)
{
perror("semctl");
exit(-1);
}
return 0;
}

int sem_p(void) //P操作
{
num--;
struct sembuf sem;
sem.sem_num = 0;
sem.sem_op = -1;
sem.sem_flg = SEM_UNDO;

if (semop(semid, &sem, 1) == -1)
{
perror("semop p");
exit(-1);
}
printf("还有%d个\n",num);
fflush(stdout);
return 0;
}

int sem_v(void) //V操作
{
num++;
struct sembuf sem;
sem.sem_num = 0;
sem.sem_op = +1;
sem.sem_flg = SEM_UNDO;

if (semop(semid, &sem, 1) == -1)
{
perror("semop v");
exit(-1);
}
return 0;
}

void sem_del(void) //删除信号
{
union semun semval;
if (semctl(semid, 0, IPC_RMID, semval) == -1)
{
perror("semdel");
exit(-1);
}
}

...全文
108 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
cocat 2010-06-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xu044 的回复:]
你的意思是不是使用XSI信号量来实现PV呀?
其实POSIX信号量的sem_wait和sem_post就是典型的PV操作,你上面实现的PV不够原子,如果使用多进程的话,num要放在共享存储区,这时多个进程会竞争使用num,如果你非要自己实现PV的话,建议结合互斥量。
[/Quote]

不是我非要~我是刚刚开始学~只学到信号量~别的我还真不会~
xu044 2010-06-08
  • 打赏
  • 举报
回复
我用多进程写了一个,你可以试着把我使用的POSIX信号量换成你自己实现的PV。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>

#define NUM 20

int main()
{
int i, fd, index;
sem_t *sem_ptr;
pid_t pids[NUM], pid;

fd = open("/dev/zero", O_RDWR);
sem_ptr = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
sem_init(sem_ptr, 1, 10);

for (i = 0; i < NUM; i++)
{
index = i + 1;
if((pids[i] = fork()) > 0)
continue; //parent continue fork

//child
sem_wait(sem_ptr);
printf("I'm Num.%d, I have got a boat!\n", index);
sleep(1);
sem_post(sem_ptr);
printf("I'm Num.%d, I have given back the boat!\n", index);

exit(0);
}

while ((pid = waitpid(-1, NULL, 0)) > 0)
;
puts("GAME OVER!");
return 0;
}

justin_luhui 2010-06-08
  • 打赏
  • 举报
回复
标记一下
xu044 2010-06-08
  • 打赏
  • 举报
回复
你的意思是不是使用XSI信号量来实现PV呀?
其实POSIX信号量的sem_wait和sem_post就是典型的PV操作,你上面实现的PV不够原子,如果使用多进程的话,num要放在共享存储区,这时多个进程会竞争使用num,如果你非要自己实现PV的话,建议结合互斥量。
cocat 2010-06-08
  • 打赏
  • 举报
回复
非常感谢~不过我想以信号量PV操作那样来实现
xu044 2010-06-08
  • 打赏
  • 举报
回复
直接用POSIX信号量就行。
用多进程和多线程都可以,下面我用多线程写了一个,不知道是不是你想要的!
编译的时候别忘了加 -pthread

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define NUM 20 //20个客户

sem_t sem;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int count = 0;

void * thread_routine(void *arg);

int main()
{
int i;
pthread_t tid;

sem_init(&sem, 0, 10);
for (i = 0; i < NUM; i++)
{
pthread_mutex_lock(&mutex);
count++;
pthread_mutex_unlock(&mutex);

if(pthread_create(&tid, NULL, thread_routine, (void *)(i+1)) != 0)
perror("Cann't create thread:");
}

pthread_mutex_lock(&mutex);
while (count != 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
puts("GAME OVER!");
return 0;
}


void * thread_routine(void *arg)
{
int num = (int)arg;
pthread_detach(pthread_self());

sem_wait(&sem);
printf("I'm Num.%d, I have got a boat!\n", num);
sleep(1);
sem_post(&sem);

pthread_mutex_lock(&mutex);
count--;
pthread_mutex_unlock(&mutex);
printf("I'm Num.%d, I have given back the boat!\n", num);
pthread_cond_signal(&cond);

return;
}

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧