1.管道
1.1普通管道
#include
#include
#include
#include
#include
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char *p_wbuf;
int r_num;
memset(buf_r, 0, sizeof(buf_r));
if(pipe(pipe_fd) < 0)
{
printf("pipe create error!/n");
return -1;
}
if((pid = fork()) == 0)
{
printf("/n");
close(pipe_fd[1]);
sleep(2);
if((r_num = read(pipe_fd[0], buf_r, 100)) > 0)
{
printf("%d numbers read from the pipe is %s/n", r_num, buf_r);
}
close(pipe_fd[0]);
exit(0);
}
else if(pid > 0)
{
close(pipe_fd[0]);
if(write(pipe_fd[1], "Hello", 5) != -1)
printf("parent write surcess/n");
if(write(pipe_fd[1], "pipe", 5) != -1)
printf("parent write success/n");
close(pipe_fd[1]);
sleep(2);
waitpid(pid, NULL, 0);
exit(0);
}
}
1.2 基于文件流管理
/*流管道*/
#include
#include
#include
#include
#include
#define BUFSIZE 1024
int main()
{
FILE *fp;
char *cmd = "ps -ef";
char buf[BUFSIZE];
buf[BUFSIZE] = '/0';
if((fp = popen(cmd, "r")) == NULL)
perror("popen");
while((fgets(buf, BUFSIZE, fp)) != NULL)
printf("%s", buf);
pclose(fp);
exit(0);
}
1.3命名管道
读
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO "/tmp/myfifo"
int
main(int argc, char **argv)
{
char buf_r[100];
int fd;
int nread;
if((mkfifo(FIFO, O_CREAT | O_EXCL) < 0) && (errno != EEXIST))
printf("cannot create fifoserver/n");
printf("Preparing for reading bytes../n");
memset(buf_r, 0 , sizeof(buf_r));
fd = open(FIFO, O_RDONLY | O_NONBLOCK, 0);
if(fd == -1)
{
perror("open FIFO failed!/n");
exit(1);
}
while(1)
{
memset(buf_r, 0, sizeof(buf_r));
if((nread = read(fd, buf_r, 100)) == -1)
{
if(errno == EAGAIN)
printf("no data yet]n");
}
printf("read %s, from FIFO/n", buf_r);
sleep(1);
}
pause();
unlink(FIFO);
}
写
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO_SERVER"/tmp/myfifo"
int
main(int argc, char ** argv)
{
int fd;
char w_buf[100];
int nwrite;
fd = open(FIFO_SERVER, O_WRONLY | O_NONBLOCK, 0);
if(fd == -1)
{
if(errno == ENXIO)
printf("open error, no reading process/n");
}
if(argc == 1)
printf("Please send something/n");
strcpy(w_buf, argv[1]);
if((nwrite = write(fd, w_buf, 100)) == -1)
{
if(errno == EAGAIN)
printf("no data yet/n");
}
else
printf("write %d characters: %s/n", nwrite, w_buf);
}
信号及信号集
#include
#include
#include
void my_func(int sig_no)
{
if(sig_no == SIGINT)
printf("I have get SIGINT/n");
else if(sig_no == SIGQUIT)
printf("I have get SIGQUIT/n");
}
int main()
{
printf("Waiting for signal SIGINT or SIGQUIT/n");
signal(SIGINT, my_func);
signal(SIGQUIT, my_func);
pause();
exit(0);
}
2. 信号集
#include
#include
#include
void my_func(int signum)
{
printf("If you want to quit, please try SIGQUIT/n");
}
int main()
{
sigset_t set, pendset;
struct sigaction action1, action2;
if(sigemptyset(&set) < 0)
perror("sigemptyset");
if(sigaddset(&set, SIGQUIT) < 0)
perror("sigaddset");
if(sigaddset(&set, SIGINT) < 0)
perror("sigaddset");
if(sigprocmask(SIG_BLOCK, &set, NULL) < 0)
perror("sigprocmask");
else
{
printf("block/n");
sleep(5);
}
if(sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)
perror("sigprocmask");
else
printf("unblock/n");
while(1)
{
if(sigismember(&set, SIGINT))
{
sigemptyset(&action1.sa_mask);
action1.sa_handler = my_func;
sigaction(SIGINT, &action1, NULL);
}
else if(sigismember(&set, SIGQUIT))
{
sigemptyset(&action2.sa_mask);
action2.sa_handler = SIG_DFL;
sigaction(SIGTERM, &action2, NULL);
}
}
}
3. 共享内存(大型数据传输)
#include
#include
#include
#include
#include
#include
#include
#define BUFSZ 2048
int main()
{
int shmid;
char *shmadd;
key_t key;
if((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(1);
}
if((shmid = shmget(IPC_PRIVATE, BUFSZ, 0666)) < 0)
{
perror("shmget");
exit(1);
}
else
{
printf("created shared-memory: %d/n", shmid);
system("ipcs –m");
}
if((shmadd = shmat(shmid, 0, 0)) < (char*)0)
{
perror("shmat");
exit(1);
}
else
{
printf("attached shared-memory/n");
system("ipcs –m");
}
if(shmdt(shmadd) < 0)
{
perror("shmdt");
exit(1);
}
else
{
printf("dettached shared-memory/n");
system("ipcs -m");
}
exit(0);
}
4. 消息队列(少量数据传输)
#include
#include
#include
#include
#include
#include
#include
#define BUFSZ 512
struct message
{
long msg_type;
char msg_text[BUFSZ];
};
int main()
{
int qid;
key_t key;
int len;
struct message msg;
if((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(1);
}
if((qid = msgget(key, IPC_CREAT | 0666)) == -1)
{
perror("msgget");
exit(1);
}
printf("opened queue %d/n", qid);
puts("Please enter the message to queue:");
if((fgets(msg.msg_text, BUFSZ, stdin)) == NULL)
{
puts("no message");
exit(1);
}
msg.msg_type = getpid();
len = strlen(msg.msg_text);
if(msgsnd(qid, &msg, len, 0) < 0)
{
perror("message posted");
exit(1);
}
printf("message is :%s/n", msg.msg_text);
if(msgctl(qid, IPC_RMID, NULL) < 0)
{
perror("msgctl");
exit(1);
}
exit(0);
}
5. 守护进程
守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,在系统关闭时终止。因为它们没有控制终端,所以说它们是在后台进程的。所有守护进程都以超级用户优先级运行。所有守护进程的父进程都init进程。守护进程一般是进程组的首进程。
查看守护进程命令:
ps –ef
创建守护进程的步骤:
(1)创建子进程,父进程退出。
保证子进程不是一个进程组的首进程,是调用setsid调用的必要的前提条件。
(2)调用setsid以创建一个新的会话,并担任该会话组的组长。调用setsid作用有三:
(a)成为新的会话组(一个或多个进程组)的首进程。
(b)成为一个新进程组的首进程。
(c)脱离控制终端。
(3)改变当前目录为根目录
chdir(“/”);
(4)重设文件权限掩码
unmask(0);表示打开所有文件权限
(5)关闭不再需要的文件描述符
#include
#include
#include
#include
#include
#include
#include
#define MAXFILE 65535
int main()
{
pid_t pc;
int i, fd, len;
char *buf = "This is a Dameon/n";
len = strlen(buf);
pc = fork();
if(pc < 0)
{
printf("error fork/n");
exit(1);
}
else if(pc > 0)
{
exit(0);
}
setsid();
chdir("/");
umask(0);
for(i = 0; i < MAXFILE; i++)
close(i);
while(1)
{
if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0)
{
perror("open");
exit(1);
}
write(fd, buf, len+1);
close(fd);
sleep(5);
}
}