linux - 题目

文章目录

题目

1.请编写一个程序,设置SIGINT和SIGQUIT信号,并在该程序中实现从文件中读取信息的操作,
并保证在读取文件且只有在读取文件的过程中不会被发送的SIGINT和SIGQUIT信号所打断。

//请编写一个程序,设置SIGINT和SIGQUIT信号,并在该程序中实现从文件中读取信息的操作,并保证在读取文件且只有在读取文件的过程中不会被发送的SIGINT和SIGQUIT信号所打断。
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void sighandler(int signo)
{
    
    
	if((signo == SIGINT) || (signo == SIGQUIT))
	{
    
    
		printf("解除阻止\n");
	}
}

int main(int argc,char* args[])
{
    
    
	int flag;			//标识文件读取状态
	sigset_t best;		//阻塞信号
	sigemptyset(&best);	//清空信号集
	sigaddset(&best,SIGINT);	//添加阻塞信号
	sigaddset(&best,SIGQUIT);	
	sigprocmask(SIG_BLOCK,&best,NULL);	//将SIG_BLOCK和best信号或操作
	if(signal(SIGINT,sighandler) == SIG_ERR)
	{
    
    
		perror("signal error");
		return -1;
	}
	if(signal(SIGQUIT,sighandler) == SIGQUIT)
	{
    
    
		perror("signal error");
		return -1;
	}
	FILE *fp = NULL;
	fp = fopen("./a.txt","r");
	if(fp == NULL)
	{
    
    
		printf("文件打开失败\n");
		return -1;
	}	
	printf("请输入是否开始读取文件 1代表读,0代表不读\n");
	scanf("%d",&flag);
	while(1)
	{
    
    
		if(flag == 1)
		{
    
    
			break;
		}
		else if(flag == 0)
		{
    
    
			pause();
		}
	}
	
	char buffer[1024];
	while(1)
	{
    
    
		memset(buffer,0,sizeof(buffer));
		char *temp = fgets(buffer,sizeof(buffer),fp);				
		if(temp == NULL)
		{
    
    
			break;
		}
		printf("buffer = %s\n",buffer);
	}
	if(fp != NULL)
	{
    
    
		fclose(fp);
	}
	printf("read ends\n");
	sigset_t uset;
	sigemptyset(&uset); 
	sigaddset(&uset,SIGINT);
	sigaddset(&uset,SIGQUIT);
	sigprocmask(SIG_BLOCK,&uset,NULL);
	while(1)
	{
    
    
		pause();
	}
	return 0;
	
}

2.编程一个基本多进程测试框架,提示用户输入进程数、和每个进程数运行圈数。进行多进程压力测试。
要求父进程能监控所有子进程的退出,避免僵尸进程。

//2、编程一个基本多进程测试框架,提示用户输入进程数、和每个进程数运行圈数。进行多进程压力测试。要求父进程能监控所有子进程的退出,避免僵尸进程。
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void TestFunc(int num)
{
    
    
	printf("%d\n",num++);
}

int main()
{
    
    
	pid_t pid;
	int process_num;
	int process_run;
	int i, j;
	printf("线程数:");
	scanf("%d",&process_num);
	printf("圈数:");
	scanf("%d",&process_run);
	for(i = 0; i < process_num; i++)
	{
    
    
		pid = fork();
		if(pid == 0)
		{
    
    
			for(j = 0; j < process_run; j++)
			{
    
    
				TestFunc(j);
			}
			exit(0);
		}
	}
	
	while(1)
	{
    
    
		wait(NULL);
	}
	printf("main ends\n");
	return 0;
}

3.信号可靠信号不可靠信号相关
编程程序,要去实现如下功能:
父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值进行打印。
提示:用sigqueue和sigaction实现

#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
/*
1因为孩子1的pid和孩子2的pid全部在父进程中
2 父进程把孩子2的pid,发给孩子1

3、孩子1有了孩子2的pid,孩子1就可以给孩子2发送信号了。
*/


int pidArray[10];   //写时拷贝copy-on-write 如果全区变量值改变,子进程另外拷贝

void myhandle(int num,siginfo_t *st, void *p)
{
    
    
	int val = 0;
	//printf("recve num:%d,data=%d\n",num,st->si_value.sival_int);
	if (num == SIGRTMIN+1)
	{
    
    
		//孩子1接收到了信号
		printf("孩子1收到信号,值:%d \n", st->si_value.sival_int);//父进程将子进程2的pid这个数据发给了,子进程1
		pidArray[1] = st->si_value.sival_int;// 子进程1将从父进程收到的数据放在本全局区pidArray[1]中
	}
	
	if (num == SIGRTMIN+2)
	{
    
    
		//孩子2接收到了信号
		printf("孩子2收到信号,值:%d \n", st->si_value.sival_int);//子进程1将自己的2*pid值发给子进程2
		pidArray[3] = st->si_value.sival_int;//子进程2将子进程1发送的数据存到本全局区中
	}
	
	if (num == SIGRTMIN+3)
	{
    
    
		//父进程接收到了信号
		printf("父进程收到信号,值:%d \n", st->si_value.sival_int);//子进程2将自己收到的数据又发给父进程
		printf("父进程中的pid[0]:%d pid[1]:%d \n", pidArray[0], pidArray[1]);//输出自己全局区中原来存的数据
		pidArray[3] = st->si_value.sival_int;//父进程将从子进程2收到的数据存入本全局区中
	}
}


int main()
{
    
    
	int i = 0;
	struct sigaction act;
	act.sa_sigaction=myhandle;
	act.sa_flags=SA_SIGINFO;
	  //注册信号 处理函数
	if(sigaction(SIGRTMIN+1,&act,NULL)==-1)
	{
    
    
	  	perror("func sigaction err:");
	  	return -2;
	 }
		  //注册信号 处理函数
	if(sigaction(SIGRTMIN+2,&act,NULL)==-1)
	{
    
    
	  	perror("func sigaction err:");
	  	return -2;
	 }
	 
	 	  //注册信号 处理函数
	if(sigaction(SIGRTMIN+3,&act,NULL)==-1)
	{
    
    
	  	perror("func sigaction err:");
	  	return -2;
	 }
	 
	 int pid = 0;
	 for (i=0; i<2; i++)
	 {
    
    
	 	//父进程可以把所有的孩子ID缓存下来
 		pidArray[i]  = pid = fork();
		if (pid == 0)
		{
    
    
			break; //如果是孩子,不参与fork
		}
		else if (pid > 0)
		{
    
    
			;
		}
 	}


	if (pid > 0)
	{
    
    
		printf("父进程运行\n");
		//父进程给进程1发送信号 把进程2的pid发过去
		  //添加额外数据
		  union sigval mysigval;
		  mysigval.sival_int=pidArray[1];

		  //发送消息
		  int res;
		  res = sigqueue(pidArray[0],SIGRTMIN+1, mysigval);

	}
	//子进程1
	if (pid==0 && i==0)
	{
    
    
		printf("子进程1运行\n");
		printf("子进程sleep\n");
		sleep(5);
		printf("子进程sleep被打断以后,全局变量有值了\n");
		
		  //添加额外数据
		  union sigval mysigval;
		  mysigval.sival_int=getpid()*2;

		  //发送消息
		  int res;
		  printf("子进程1给进程2发送信号getpid()*2:%d  \n", getpid()*2);
		  res = sigqueue(pidArray[1],SIGRTMIN+2, mysigval);
		
		exit(0);
	}
	
	
	//子进程2
	if (pid==0 && i==1)
	{
    
    
		
		sleep(10);
		printf("子进程2睡眠醒来,开始发信号\n");
		
		 //添加额外数据
		  union sigval mysigval;
		  mysigval.sival_int=pidArray[3];

		  //发送消息
		  int res;
		  printf("子进程2给父进程发送信号pidArray[3]%d  \n", pidArray[3]);
		  res = sigqueue(getppid(),SIGRTMIN+3, mysigval);
		
		exit(0);
	}
	
	sleep(2);
	int mypid = 0;
	while ( (mypid = waitpid(-1, NULL, WNOHANG)) > 0)
	{
    
    
		printf("子进程退出pid:%d \n", mypid);
	}
	
	return 0;

}


4.设计一个Shell程序,在/$HONE/test目录下建立50个目录,即user1~user50,
并设置每个目录的权限,其中其他用户的权限为:读;文件所有者的权限为:
读、写、执行;文件所有者所在组的权限为:读、执行。

#!/bin/sh
i=0
while [$i -lt 50 ]
do
    i=`expr $i + 1`
    mkdir -p ./home/user$i
    chmod 754 ./home/user$i
done

5.shell程序
编写shell程序,添加一个新组为class1,然后添加属于这个组的20个用户,
用户名的形式为stdxx,其中xx从01到20。

#!/bin/sh
i=1
while [ $i -le 2 ]
do
    if [$i -le 9]
    then
        USERNAME=systemk1t${i}
    fi
    useradd $USERNAME
    mkdir /home/$USERNAME
    chown -R $USERNAME /home/$USERNAME
    chgrp -R class1 /home/$USERNAME
    i=$(($i + 1))
done

猜你喜欢

转载自blog.csdn.net/weixin_43791961/article/details/111030630
今日推荐