- 论坛徽章:
- 0
|
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#ifdef __linux
#include <linux/sem.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/wait.h>
#else
#include <windows.h>
#endif
#define SEM_LOCK "./lock2"
#define SEM_FULL "./full2"
#define SEM_EMPTY "./empty2"
#ifdef WIN32
int myflag = 0;
#else
int myflag = IPC_CREAT|IPC_EXCL|000666;
#endif
int init(char *pathname, int value, int flag);
void setvalue(int sem_id, int value);
void mywait(int sem_id);
void release(int sem_id);
void destroy(int sem_id);
int g_lock;
int g_full;
int g_empty;
void producer();
void consumer();
int main(int argc, char **agrv)
{
int childpid1 = 0;
int childpid2 = 0;
int stat = 0;
g_lock = init(SEM_LOCK, 1, myflag);
g_full = init(SEM_FULL, 0, myflag);
g_empty = init(SEM_EMPTY, 2, myflag);
if ((g_lock < 0) || (g_full < 0) || (g_empty < 0))
perror("init error");
if ((childpid1 = fork()) == 0)
{
// consumer();
producer();
exit(0);
}
printf("wait all child\n");
waitpid(-1, 0, 0);
printf("destroy sem\n");
destroy(g_lock);
destroy(g_full);
destroy(g_empty);
printf("end main\n");
return 0;
}
void mywait(int sem_id)
{
#ifdef __linux
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = SEM_UNDO;
semop(sem_id, &buf, 1);
#endif
}
void release(int sem_id)
{
#ifdef __linux
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;
semop(sem_id, &buf, 1);
#endif
}
void setvalue(int sem_id, int value)
{
#ifdef __linux
union semun arg;
arg.val = value;
semctl(sem_id, 0 , SETVAL, arg);
#endif
}
void destroy(int sem_id)
{
#ifdef __linux
semctl(sem_id, 0, IPC_RMID);
#endif
}
int init(char *pathname, int value, int flag)
{
#ifdef __linux
union semun arg;
struct semid_ds sem_info;
int sem_id = 0;
int init_ok = 0;
key_t key = ftok(pathname, 'l');
if (key < 0)
{
printf("init()----failure :%s\n", strerror(errno));
}
printf("init()---- key = %d\n", key);
sem_id = semget(key, 1, flag);
if (sem_id >0)
{
setvalue(sem_id, value);
printf("init() ----- pathname = %s, semid = %d\n", pathname, sem_id);
return sem_id;
}
else if (sem_id <=0)
{
int tmp_errno = errno;
if (tmp_errno == EEXIST)
{
sem_id == semget(key, 1, IPC_CREAT | 00666);
if (sem_id < 0)
{
tmp_errno = errno;
printf("init() ----- open semampore : semid = %d, %s\n",
sem_id, strerror(tmp_errno));
return sem_id;
}
arg.buf = &sem_info;
if ((semctl(sem_id, 0, IPC_STAT, arg)) == -1)
{
printf("init() ----- get status :pathname = %s, semid = %d, %s\n",
pathname, sem_id, strerror(errno));
return -1;
}
else
{
if (arg.buf->sem_otime == 0)
setvalue(sem_id, value);
printf("init() ----- , setvalue :pathname = %s, semid = %d, %s\n",
pathname, sem_id, strerror(errno));
return sem_id;
}
}
else
{
printf("init() ----- other error :pathname = %s, semid = %d, %s\n",
pathname, sem_id, strerror(tmp_errno));
}
}
#endif
return -1;
}
void producer()
{
int i=0;
for (i=0; i<10; i++)
{
mywait(g_empty);
mywait(g_lock);
printf("process = %d, produce()---- i = %d\n", getpid(), i);
release(g_lock);
release(g_full);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
}
void consumer()
{
int i=0;
for (i=0; i<10; i++)
{
mywait(g_full);
mywait(g_lock);
printf("process = %d, consumer()---- i = %d\n", getpid(), i);
release(g_lock);
release(g_empty);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
}
//出错代码段,sem_id = -1, strerror(tmp_errno)) 为files exist,如何得到确的sem_id,环境fedora6
sem_id == semget(key, 1, IPC_CREAT | 00666);
if (sem_id < 0)
{
tmp_errno = errno;
printf("init() ----- open semampore : semid = %d, %s\n",
sem_id, strerror(tmp_errno));
return sem_id;
}
if ((childpid1 = fork()) == 0)
{
// consumer();
producer(); //如果是consumer使用上面那行
exit(0);
}
[ 本帖最后由 lxrlxr2002 于 2008-3-21 17:26 编辑 ] |
|