1多进程操作函数
(1)fork函数
用于增加一个进程,返回的pid如果大于0,表示后续操作在父进程里执行;返回的pid如果等于0,表示后续操作在子进程里执行;返回pid小于0,表示增加进程失败。
在fork函数执行前建立的局部变量,将在子进程中产生一份拷贝。原话是这样说的:The child process and the parent process run in separate memory spaces. At the time of fork() both memory spaces have the same content. “子进程和父进程运行在独立的内存空间中,fork函数执行时,两个内存空间有相同的内容。”当然这是针对一般的变量,有一些特殊的变量并不会被拷贝,这属于进阶内容了,这里暂不讨论。
(2)wait函数
在父进程中执行,等待子进程停止或销毁,原话:wait for a child process to stop or terminate.
2信号量操作函数
信号量主要用于进程间同步。
sem_post函数执行时,将信号量加1,然后执行后续的操作。
sem_wait函数执行时,等待信号量,如果信号量大于1,则减1,然后执行以后的操作。否则一直等待在这里。
3.程序实例
在下面的实例中,使用fork函数建立了两个进程,父进程执行完消息发送后,释放信号量;子进程收到信号量后再去读取信号。子进程执行完毕后进程销毁,这时父进程利用wait函数收到信息,再使用mq_unlink函数清除消息队列(外在表现是删除了消息队列缓存文件),程序退出。
执行结果:
child : before recv msg, pi is -1.000000.
father : msg id is 0x3A450.
father : send pi is 3.141590.
child : msg id is 0x52870.
child : recv pi is 3.141590.
4.源代码
// 消息队列:
// 2017-05-11
#include
#include
#include
//消息队列
#include
//多进程 (fork)
#include
//信号量 #include
//wait函数 #include
//定义了系统中大量的宏 struct MsgType { int len; float pi; }; sem_t mySem; int main() { mqd_t msgq_id; struct MsgType msg; unsigned int prio; const char *file = "\\mqex1"; int fpid = fork(); //产生一个子进程 // 进入父进程 if(fpid > 0) { msg.len = 8; msg.pi = 3.14159; // 新建或打开一个消息队列 msgq_id = mq_open(file, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, NULL); printf("father : msg id is 0x%X.\n",(unsigned int)msgq_id); fflush(stdout); if (msgq_id == (mqd_t) -1) { perror("mq_open error"); exit(1); } printf("father : send pi is %f.\n",msg.pi); fflush(stdout); // 发送消息 if (mq_send(msgq_id, (char*) &msg, sizeof(struct MsgType), prio) == -1) { perror("mq_send"); exit(1); } //发送信号量 sem_post(&mySem); // 关闭消息队列 if (mq_close(msgq_id) == -1) { perror("mq_close"); exit(1); } //等待子进程完成任务 //sleep(1); wait(NULL); // 删除消息队列缓存文件 if (mq_unlink(file) == -1) { perror("mq_unlink"); exit(1); } } //进入子进程 if(fpid == 0) { msg.len = 8; msg.pi = -1; printf("child : before recv msg, pi is %f.\n",msg.pi); fflush(stdout); // 新建或打开一个消息队列 msgq_id = mq_open(file, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, NULL); printf("child : msg id is 0x%X.\n",(unsigned int)msgq_id); if (msgq_id == (mqd_t) -1) { perror("mq_open error"); exit(1); } // 等待信号量 sem_wait(&mySem); // 接收消息 if (mq_receive(msgq_id, (char*) &msg, 8192, &prio) == -1) { perror("mq_receive"); exit(1); } printf("child : recv pi is %f.\n",msg.pi); fflush(stdout); // 关闭消息队列 if (mq_close(msgq_id) == -1) { perror("mq_close"); exit(1); } /* if (mq_unlink(file) == -1) { perror("mq_unlink"); exit(1); } */ } if(fpid<0) //开辟子进程失败则退出 { perror("fork"); exit(1); } return 0; }