Linux笔试题

1. 程序代码如下,请按执行顺序写出输出结果: 

int main()
{  pid_t  pid1,pid2;
  
   if((pid1=fork()) = = 0)
{
   sleep(3);
   printf(“info1 from child process_1\n”);
   exit(0);
   printf(“info2 from child process_1\n”);
}
else
{
  if((pid2=fork()) = = 0)
  {
     sleep(1);
     printf(“info1 from child process_2\n”);
     exit(0);
  }
  else
  {
     wait(NULL);
     wait(NULL);
     printf(“info1 from parent process\n”);
     printf(“info2 from parent process”);
     _exit(0);
  }
}  

 运行结果:

linux@linux:/mnt/hgfs/linuxshare/linux_code/test$ ./test01
info1 from child process_2
info1 from child process_1
info1 from parent process

为什么不打印   printf(“info2 from parent process”);????

在C语言中,printf函数通常在输出完内容后会等待标准输出缓冲区刷新,以确保内容被正确地输出到屏幕上。

但是,在程序执行结束时,标准输出缓冲区不会自动刷新。

因此,如果在printf之后没有添加换行符\n,而是直接调用exit或_exit来退出程序,可能会导致输出被缓冲,而没有立即被打印到屏幕上。

当你在printf("info2 from parent process\n");之后加上\n时,会强制刷新标准输出缓冲区,使得之前的内容立即被输出到屏幕上。

而当你没有加上\n时,程序可能会在调用exit或_exit之前退出,导致缓冲区中的内容没有被输出。

因此,为了确保printf的输出能够立即被打印到屏幕上,建议在printf的最后添加换行符\n。

 2. 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

write(1,"A",1);:

        这行代码使用 write 函数将字符 'A' 写入文件描述符为1的位置。在UNIX系统中,文件描述符1通常是标准输出(stdout),所以这行代码将字符 'A' 写入到标准输出中,即将字符 'A' 打印到控制台上。

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<signal.h>
#include<fcntl.h>

sem_t sem[3];
char* shmaddr;

void semdestroyhandle(int sig)
{
	sem_destroy(&sem[0]);
	sem_destroy(&sem[1]);
	sem_destroy(&sem[2]);
	exit(0);
}

void* func1(void* arg)
{
	while(1)
	{
		sem_wait(&sem[0]);
		write(1,"A",1);
		sem_post(&sem[1]);
	}
}

void* func2(void* arg)
{
	while(1)
	{
		sem_wait(&sem[1]);
		write(1,"B",1);
		sem_post(&sem[2]);

	}
}

void* func3(void* arg)
{
	while(1)
	{
		sem_wait(&sem[2]);
		write(1,"C",1);
		sleep(3);
		sem_post(&sem[0]);
	}
}

struct sigaction oldact;
int main()
{	
	struct sigaction act;
	act.sa_handler = semdestroyhandle;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaction(SIGINT,&act,&oldact);

	pthread_t tid[3];


	

	sem_init(&sem[0],0,1);
	sem_init(&sem[1],0,0);
	sem_init(&sem[2],0,0);

	pthread_create(&tid[0],NULL,func1,NULL);
	pthread_create(&tid[1],NULL,func2,NULL);
	pthread_create(&tid[2],NULL,func3,NULL);

	pthread_join(tid[0],NULL);
	pthread_join(tid[1],NULL);
	pthread_join(tid[2],NULL);



	return 0;
}

 运行结果:

linux@linux:/mnt/hgfs/linuxshare/linux_code/test$ ./test02
ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC^Clinux@linux:/mnt/hgfs/linuxshare/linux_code/test$ 

3. 编写程序实现如下功能

reader.c     从argv[1]所指定的文件中读取内容,依次写到管道/home/linux/myfifo中

writer.c     从管道/home/linux/myfifo中读取内容,写到argv[1]所指定的文件中并保存 

代码中可省略头文件,/home/linux/myfifo无需创建

在linux下关于int main( int argc, char* argv[] )含义解析及调试_linuxc int main int argc-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_43053387/article/details/88034871

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
int main(int argc,const char* argv[])
{
	if(argc != 2)
	{
		printf("%s filename\n",argv[0]);
		exit(1);
	}

	int fd = open(argv[1],O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return 0;
	}

	int fifo_fd = open("/home/linux/myfifo",O_WRONLY);
	if(fifo_fd < 0)
	{
		perror("open");
		return 0;
	}
	
	char buf[1024];
	int n;
	while((n = read(fd,buf,sizeof(buf))) > 0)
	{
		write(fifo_fd,buf,n);
	}

	close(fd);
	close(fifo_fd);

	return 0;

}

要查看命名管道中的内容,您可以使用命令行工具来读取管道,并将其内容输出到终端。 


这里有几种方法可以实现:

使用 cat 命令:
您可以使用 cat 命令将管道中的内容输出到终端。例如:

cat /home/linux/myfifo
这将显示 /home/linux/myfifo 管道中的内容。

使用 less 或 more 命令:
您可以使用 less 或 more 命令逐页查看管道中的内容。例如:

less /home/linux/myfifo
或者
more /home/linux/myfifo
您可以使用键盘上的箭头键或空格键来滚动内容。

使用 tail 命令:
您可以使用 tail 命令查看管道中最新添加的内容。例如:

tail -f /home/linux/myfifo
-f 选项将使 tail 命令保持打开状态,并在管道中有新内容时实时显示。

 执行以下操作来查找文件:

在当前目录中查找: 如果您不记得将 example.txt 放在了哪里,可以在当前目录中执行以下命令来查找:

ls -l example.txt
这将列出当前目录中的所有文件及其属性。如果 example.txt 存在于当前目录中,它将显示在列表中。

在其他目录中查找: 如果您认为 example.txt 可能存储在其他目录中,您可以使用 cd 命令更改目录,然后使用 ls 命令查找。例如:

cd /path/to/directory
ls -l example.txt
这将更改到指定目录并列出该目录中的文件。如果找到了 example.txt 文件,它将显示在列表中。

使用搜索工具: 如果您对文件的位置毫无线索,您可以使用搜索工具,如 find 命令。例如:

find / -name "example.txt"
这将从根目录开始搜索整个文件系统,查找名为 example.txt 的文件,并显示它们的路径。

通过这些方法之一,您应该能够找到 example.txt 文件的位置。
linux@linux:~$ sudo find / -name 1.txt
[sudo] password for linux: 
/mnt/hgfs/linuxshare/linux_code/test/1.txt
/home/linux/code_Linux/code_2024_1_26/1.txt
/home/linux/code_Linux/code_2024_1_25/1.txt

linux@linux:~$ cd /mnt/hgfs/linuxshare/linux_code/test
linux@linux:/mnt/hgfs/linuxshare/linux_code/test$ ls -l 1.txt
-rwxrwxrwx 1 root root 138 Mar 20 02:44 1.txt
linux@linux:/mnt/hgfs/linuxshare/linux_code/test$ 

扩展知识点:

在C语言中,waitpid(-1, &status, 0)是一个系统调用,用于等待任意子进程结束并获取其状态。

具体含义如下:

  • 第一个参数 -1 表示等待任意子进程,无论其进程ID是多少。
  • 第二个参数 &status 是一个指向整数变量的指针,用于存储子进程的退出状态。
  • 第三个参数 0 表示等待子进程结束并暂停父进程的执行,直到有子进程结束。

这个系统调用通常在父进程中使用,用于等待子进程结束,以便父进程可以处理子进程的退出状态或者执行其他操作。

默认情况下,不会终止进程的信号是 (   )

  • A  SIGINT
  • B  SIGKILL
  • C  SIGALRM
  • D  SIGCHLD

 A SIGINT 表示中断信号,通常由用户按下 Ctrl+C 产生,用于终止进程。

B SIGKILL 表示强制终止信号,无法被忽略、阻塞或处理,可以强制终止进程。

C SIGALRM 表示定时器信号,通常用于定时器的触发。

D SIGCHLD 表示子进程状态改变,例如子进程终止或停止时发送给父进程的信号。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值