gdb调试生产者消费者

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;
}
end

Comments

留言