gdb调试生产者、消费者
# 编译生产者
gcc -g shm-posix-producer.c -o shm-posix-producer -lrt
# 编译消费者
gcc -g shm-posix-consumer.c -o shm-posix-consumer -lrt
调试生产者
gdb ./shm-posix-producer
设置断点
运行调试
运行消费者
重新打开一个窗口,运行消费者
继续调试生产者并查看消费者情况 可以看到多了一条新生产的消息
生产者代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <x86_64-linux-gnu/sys/shm.h>
#include <x86_64-linux-gnu/sys/stat.h>
#include <x86_64-linux-gnu/sys/mman.h>
int main()
{
const int SIZE = 4096;
const char *name = "OS";
const char *message0= "Studying ";
const char *message1= "Operating Systems ";
const char *message2= "Is Fun!";
int shm_fd;
void *ptr;
/* create the shared memory segment */
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory segment */
ftruncate(shm_fd, SIZE);
/* now map the shared memory segment in the address space of the process */
ptr = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed\n");
return -1;
}
/**
* Now write to the shared memory region.
*
* Note we must increment the value of ptr after each write.
*/
sprintf(ptr,"%s",message0);
ptr += strlen(message0);
sprintf(ptr,"%s",message1);
ptr += strlen(message1);
sprintf(ptr,"%s",message2);
ptr += strlen(message2);
return 0;
}
消费者代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <x86_64-linux-gnu/sys/shm.h>
#include <x86_64-linux-gnu/sys/stat.h>
#include <x86_64-linux-gnu/sys/mman.h>
int main()
{
const char *name = "OS";
const int SIZE = 4096;
int shm_fd;
void *ptr;
int i;
/* open the shared memory segment */
shm_fd = shm_open(name, O_RDONLY, 0666);
if (shm_fd == -1) {
printf("shared memory failed\n");
exit(-1);
}
/* now map the shared memory segment in the address space of the process */
ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed\n");
exit(-1);
}
/* now read from the shared memory region */
int len = 0;i=0;
while(i<3){
if(strlen(ptr)>len){
printf("%s\n", (char *)ptr+len);
len = strlen(ptr);
i++;
}
}
/* remove the shared memory segment */
if (shm_unlink(name) == -1) {
printf("Error removing %s\n",name);
exit(-1);
}
return 0;
}
课本P82 Windows创建子进程函数
进程创建采用Windows API函数CreateProcess(),它类似于fork()。不过,fork()让子进程继承了父进程的地址空间,而CreateProcess()在进程创建时要求将一个特定程序加载到子进程的地址空间。再者,fork()不需要传递任何参数,而CreateProcess()需要传递至少10个参数
#include <windows.h>
#include <stdio.h>
int main(){
STARTUPINFO si;
PROCESS_INFORMATION pi;
// allocate memory
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
ZeroMemory(&pi,sizeof(pi));
// create child process
if(!CreateProcess(NULL /* use command line */,"C:\\Users\\lenovo\\Desktop\\test\\test.exe" /* command */,NULL /* don't inherit process handle */,NULL /* don't inherit thread handle */,FALSE /* disable handle inheritance */,0 /* no creation flags */,NULL /* use parent's environment block */,NULL /* use parent's existing directory */,&si,&pi)){
fprintf(stderr,"Create Process Failed");
return -1;
}
// parent will wait for the chile to complete
WaitForSingleObject(pi.hProcess,INFINITE);
printf("Child Complete");
// close handles
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
传递给CreateProcess()的头两个参数是应用程序名称和命令行参数。如果应用程序名称为NULL(这里就是NULL),那么命令行参数指定了所要加载的应用程序。这个例子中,加载的是test.exe程序。除了这两个初始参数之外,这里使用系统默认参数来继承进程和线程句柄,并指定没有创建标志;另外,这里还使用了父进程的已有环境块和启动目录。最后,提供了两个指向程序刚开始时所创建的结构STARTYPINFO和PROCESS_INFORAMATION的指针。Windows中的WaitForSingleObject()与wait()相当,用于等待进程完成,它的参数指定了子进程的句柄即pi.hProcess。一旦子进程退出,控制从函数WaitForSingleObject()会回到父进程
输出结果:
修改程序,使得每个进程只打印对应的一个pid
原程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
printf("%d\n",getpid());
fork(); wait(NULL);
printf("%d\n",getpid());
fork(); wait(NULL);
printf("%d\n",getpid());
fork(); wait(NULL);
printf("%d\n",getpid());
return 0;
}
修改后程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
int a=(int)getpid();
printf("%d\n",a);
fork();wait(NULL);
int b=(int)getpid();
if(b!=a)printf("%d\n",b);
fork();wait(NULL);
int c=(int)getpid();
if(c!=a&&c!=b)printf("%d\n",c);
fork();wait(NULL);
int d=(int)getpid();
if(d!=c&&d!=b&&d!=a)printf("%d\n",d);
return 0;
}
Comments