65,211
社区成员
发帖
与我相关
我的任务
分享#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#define FIFO_FILE ".fifo_test"
void *g_addr;
int *g_sign;
pthread_mutex_t *p_mutex;
pthread_cond_t *p_cond_full;
pthread_cond_t *p_cond_empty;
/*从FD读N个字节,成功返回n>=0 不成功-1*/
static ssize_t _pipe_readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = (char*)vptr;
nleft = n;
while (nleft > 0)
{
nread = read(fd, ptr, nleft);
if (nread < 0)
{
if (errno == EINTR)
{
continue;
}
else if (errno == EAGAIN || errno == EWOULDBLOCK)
{
continue;
}
else
{
return - 1;
}
}
else if (nread == 0)
{
//closed
break;
}
nleft -= nread;
ptr += nread;
}
return (n - nleft);
}
/*写FD N个字节,成功返回n>=0 不成功-1*/
static ssize_t _pipe_writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (char*)vptr;
nleft = n;
while (nleft > 0)
{
nwritten = write(fd, ptr, nleft);
if (nwritten <= 0)
{
if (errno == EINTR)
{
continue;
}
else if (errno == EAGAIN || errno == EWOULDBLOCK)
{
continue;
}
else
{
return - 1;
}
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
int set_gmem(void **addr)
{
int fd;
fd = open("/dev/zero", O_RDWR);
if (fd == -1)
{
perror("open");
return -1;
}
*addr = mmap(0, sizeof(pthread_mutex_t) + 2 * sizeof(pthread_cond_t) + sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (*addr == MAP_FAILED)
{
perror("mmap");
return - 1;
}
return 0;
}
void go_over(int sig)
{
fprintf(stdout, "\n%d sig %d now go over!\n", sig, getpid());
unlink(FIFO_FILE);
pthread_mutex_destroy(p_mutex);
pthread_cond_destroy(p_cond_empty);
pthread_cond_destroy(p_cond_full);
munmap(g_addr, sizeof(pthread_mutex_t) + 2 * sizeof(pthread_cond_t) + sizeof(int));
exit(0);
}
int main()
{
int fd;
pid_t pid;
int sig;
char l_buff[48];
pthread_condattr_t condattr;
pthread_mutexattr_t mutexattr;
/*清信号,留下结束程序用*/
for (sig = 1; sig <= SIGRTMAX; sig ++)
{
if (sig != SIGINT && sig != SIGUSR2)
{
signal(sig, SIG_IGN);
}
}
signal(SIGINT, go_over);
if (set_gmem(&g_addr) == -1)
return -1;
p_mutex = (pthread_mutex_t *)g_addr;
p_cond_full = (pthread_cond_t *)(p_mutex + 1);
p_cond_empty = p_cond_full + 1;
g_sign = (int *)(p_cond_empty + 1);
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(p_mutex, &mutexattr);
pthread_cond_init(p_cond_full, &condattr);
pthread_cond_init(p_cond_empty, &condattr);
unlink(FIFO_FILE);
if (mkfifo(FIFO_FILE, 0777) != 0)
{
perror("mkfifo");
return -1;
}
*g_sign = 0;
pid = fork();
if (pid < 0)
{
perror("fork");
return -1;
}
else if (pid > 0)
{
fd = open(FIFO_FILE, O_WRONLY);
if (fd < 0)
{
perror("open");
return -1;
}
for (;;)
{
pthread_mutex_lock(p_mutex);
while (*g_sign != 0)
{
pthread_cond_wait(p_cond_empty, p_mutex);
}
_pipe_writen(fd, "Hello World", 11);
fprintf(stdout, "%d write Hello World\n", getpid());
*g_sign = 1;
pthread_cond_broadcast(p_cond_full);
pthread_mutex_unlock(p_mutex);
}
close(fd);
}
else
{
fd = open(FIFO_FILE, O_RDONLY);
if (fd < 0)
{
perror("open");
return -1;
}
for (;;)
{
pthread_mutex_lock(p_mutex);
while (*g_sign != 1)
{
pthread_cond_wait(p_cond_full, p_mutex);
}
memset(l_buff, 0, sizeof(l_buff));
_pipe_readn(fd, l_buff, 11);
fprintf(stdout, "%d read %s\n", getpid(), l_buff);
*g_sign = 0;
pthread_cond_broadcast(p_cond_empty);
pthread_mutex_unlock(p_mutex);
}
close(fd);
}
return 0;
}