@MicroCai
2015-03-22T17:26:27.000000Z
字数 5988
阅读 2751
计算机基础
「计算机基础」系列用以复习基础之用,文章整理自网络
本文代码是大学时期整理的,放在 我的 CSDN 下载频道,在 Linux 平台下全部编译通过。
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int pipe_fd[2];
pid_t pid;
char r_buf[100];
char w_buf[4];
char* p_wbuf;
int r_num;
int cmd;
memset(r_buf, 0, sizeof(r_buf));
memset(w_buf, 0, sizeof(r_buf));
p_wbuf = w_buf;
if(pipe(pipe_fd) < 0)
{
printf("pipe create error\n");
return -1;
}
if((pid=fork()) == 0)
{
printf("child\n");
printf("\n");
close(pipe_fd[1]);
sleep(3);//确保父进程关闭写端
r_num = read(pipe_fd[0], r_buf,100);
printf("read num is %d the data read from the pipe is %d\n", r_num, atoi(r_buf));
close(pipe_fd[0]);
printf("child exit\n");
}
else if(pid > 0)
{
printf("parent\n");
close(pipe_fd[0]);//read
strcpy(w_buf, "111");
if(write(pipe_fd[1], w_buf,4) != -1)
printf("parent write over\n");
close(pipe_fd[1]);//write
printf("parent close fd[1] over\n");
printf("parent exit\n");
}
exit(0);
}
/*
功能: 创建信号量
参数:
char *pszSemFile 文件名
char cId ID
int iSems 多少个信号量
int *piInitvVal 对应信号量的初始值数组指针
返回:
-1 错误
成功信号量id
*/
int CreateSem(char *pszSemFile, char cId, int iSems, int *piInitvVal)
{
key_t key;
int iSemId;
int i;
if ((key = GetIpcKey(pszSemFile, cId)) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "GetIpcKey( %s, %d ) return %d", pszSemFile, cId, key);
return ( -1 );
}
if ((iSemId = semget(key, iSems, 0666|IPC_CREAT|IPC_EXCL)) < 0)
{
if (errno == EEXIST)
{
return(GetSem(pszSemFile, cId, iSems));
}
WriteLogTxt(FILELINE, LOG_FILE, "CreateSem(): Semget fail. errno[%d]", errno);
return(-1);
}
for (i = 0; i < iSems; i++)
{
if (semctl(iSemId, i, SETVAL, piInitvVal[i]) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "CreateSem(): Semctl fail. errno[%d]", errno);
return(-1);
}
}
return ( iSemId );
}
/*
功能: 获取信号量
参数:
char *pszSemFile 文件名
char cId ID
int iSems 多少个信号量
返回:
-1 错误
成功信号量id
*/
int GetSem(char *pszSemFile, char cId, int iSems)
{
key_t key;
int iSemId;
if ((key = GetIpcKey(pszSemFile, cId)) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "GetIpcKey( %s, %d ) return %d", pszSemFile, cId, key);
return ( -1 );
}
if ((iSemId = semget(key, iSems, 0)) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "GetSem(): semget fail! errno[%d]", errno);
return(-1);
}
return (iSemId);
}
/*
功能: 信号量PV操作
参数:
char *pszSemFile 文件名
char cId ID
int iSems 多少个信号量
struct sembuf *pstSemBuf
返回:
0 成功
其它错误
*/
int PVSem(char *pszSemFile, char cId, int iSems, struct sembuf *pstSemBuf)
{
int iSemId;
if ((iSemId = GetSem(pszSemFile, cId, iSems)) < 0)
{
return ( -1 );
}
if (semop(iSemId, pstSemBuf, 1) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "PV():Semaphore operater fail! errno[%d]", errno);
return ( -1 );
}
return ( 0 );
}
/*
功能: 删除信号量
参数:
char *pszSemFile 文件名
char cId ID
int iSems 多少个信号量
返回:
0 成功
其它错误
*/
int RmSem(char *pszSemFile, char cId, int iSems)
{
int iSemId;
if ((iSemId = GetSem(pszSemFile, cId, iSems)) < 0)
{
return ( -1 );
}
if (semctl(iSemId, 0, IPC_RMID, 0) < 0)
{
WriteLogTxt(FILELINE, LOG_FILE, "RmSem(): semctl fail! errno[%d]", errno);
return ( -1 );
}
return ( 0 );
}
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void msg_stat(int, struct msqid_ds);
int main(void)
{
int gflags,sflags,rflags;
key_t key;
int msgid;
int reval;
struct msgsbuf{
int mtype;
char mtext[1024];
}msg_sbuf, msg_rbuf;
struct msqid_ds msg_ginfo,msg_sinfo;
char *msgpath="/root/msgid";
key=ftok(msgpath,'b');
gflags=IPC_CREAT;
msgid=msgget(key,gflags|00666);
if(msgid==-1)
{
printf("msg create error\n");
return;
}
//创建一个消息队列后,输出消息队列缺省属性
msg_stat(msgid,msg_ginfo);
sflags=IPC_NOWAIT;
msg_sbuf.mtype=10;
bzero(msg_sbuf.mtext, 1024);
strcpy(msg_sbuf.mtext, "hello\n");
reval=msgsnd(msgid,&msg_sbuf,sizeof(msg_sbuf.mtext),sflags);
if(reval==-1)
{
printf("message send error\n");
}
//发送一个消息后,输出消息队列属性
msg_stat(msgid,msg_ginfo);
rflags=IPC_NOWAIT|MSG_NOERROR;
reval=msgrcv(msgid,&msg_rbuf,1024,10,rflags);
if(reval==-1)
printf("read msg error\n");
else
{
printf("read from msg queue %d bytes\n",reval);
printf("read from msg queue data: %s\n",msg_rbuf.mtext);
}
//从消息队列中读出消息后,输出消息队列属性
msg_stat(msgid,msg_ginfo);
msg_sinfo.msg_perm.uid=8;//just a try
msg_sinfo.msg_perm.gid=8;//
msg_sinfo.msg_qbytes=16388;
//此处验证超级用户可以更改消息队列的缺省msg_qbytes
//注意这里设置的值大于缺省值
reval=msgctl(msgid,IPC_SET,&msg_sinfo);
if(reval==-1)
{
printf("msg set info error\n");
return;
}
msg_stat(msgid,msg_ginfo);
//验证设置消息队列属性
reval=msgctl(msgid,IPC_RMID,NULL);//删除消息队列
if(reval==-1)
{
printf("unlink msg queue error\n");
return;
}
}
void msg_stat(int msgid,struct msqid_ds msg_info)
{
int reval;
sleep(1);//只是为了后面输出时间的方便
reval=msgctl(msgid,IPC_STAT,&msg_info);
if(reval==-1)
{
printf("get msg info error\n");
return;
}
printf("\n");
printf("current number of bytes on queue is %d\n",msg_info.msg_cbytes);
printf("number of messages in queue is %d\n",msg_info.msg_qnum);
printf("max number of bytes on queue is %d\n",msg_info.msg_qbytes);
//每个消息队列的容量(字节数)都有限制MSGMNB,值的大小因系统而异。在创建新的消息队列时
//msg_qbytes的缺省值就是MSGMNB
printf("pid of last msgsnd is %d\n",msg_info.msg_lspid);
printf("pid of last msgrcv is %d\n",msg_info.msg_lrpid);
printf("last msgsnd time is %s", ctime(&(msg_info.msg_stime)));
printf("last msgrcv time is %s", ctime(&(msg_info.msg_rtime)));
printf("last change time is %s", ctime(&(msg_info.msg_ctime)));
printf("msg uid is %d\n",msg_info.msg_perm.uid);
printf("msg gid is %d\n",msg_info.msg_perm.gid);
}
//fifo_read.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/root/fifoserver"
int main(int argc,char** argv)
{
char r_buf[4096*2];
int fd;
int ret_size;
memset(r_buf,0,sizeof(r_buf));
if((mkfifo(FIFO_SERVER, S_IRUSR | S_IWUSR)<0)&&(errno!=EEXIST))
printf("cannot create fifoserver\n");
fd=open(FIFO_SERVER,O_RDONLY,0);
if(fd==-1)
{
printf("open %s for read error\n");
exit(1);
}
while(1)
{
memset(r_buf,0,sizeof(r_buf));
ret_size=read(fd, r_buf, 4096);
if(ret_size==-1)
{
printf("no data avlaible\n");
break;
}
printf("real read bytes %d\n", ret_size);
printf("real read : %s\n", r_buf);
}
unlink(FIFO_SERVER);
exit(1);
}
//fifo_write.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/root/fifoserver"
//参数为即将写入的字节数
int main(int argc,char** argv)
{
int fd;
char w_buf[4096*2];
int real_wnum;
memset(w_buf,0,4096*2);
fd=open(FIFO_SERVER, O_WRONLY|O_NONBLOCK); //设置非阻塞标志
if(fd==-1){
printf("open error\n");
exit(1);
}
while (1)
{
strcpy(w_buf, "hello\n");
real_wnum=write(fd,w_buf, strlen(w_buf));
if(real_wnum==-1)
{
printf("write to fifo error\n");
break;
}
else
printf("real write num is %d\n",real_wnum);
sleep(1);
}
exit(0);
}