select multiplex learning (1)

Foreword:

In the previous article, I have already learned the c/s framework model, but this model has a shortcoming, that is, the server cannot handle multiple client requests, so today we start to learn select multiplexing!

1. Everything is a file:

Everything managed by the Linux kernel can be regarded as a file! What does the kernel manage? Let's take a simple example-manage hardware, such as managing hard disks, network cards, memory, etc.! Under this design concept, all these hardware can be regarded as files.

1. What are files in Linux?

  • Narrow sense: files in the physical sense of the file system (logically associated data sets)

  • Broad sense: devices, pipes, memory, all objects managed by Linux

2. Understand the file descriptor (File Descriptor) fd:

  • A file descriptor is a non-negative integer value, essentially a handle
  • All resource identifiers that are transparent to users can be regarded as handles
  • Users interact with the kernel using file descriptors (handles)
  • The kernel operates the data structure of the corresponding resource through the file descriptor

The general operation methods of operating files are as follows:

  • open
  • read
  • write
  • close

File operation mode of IO device:

#include <stdio.h>
#include <unistd.h>
int main()
{
    
    
	int iofd =0;
	char s[] = "mytest\n";
	int len =0;
	write(0, s, sizeof(s));
	
	len = read(0, s , 2);
	s[len] = 0;
	printf("%s\n",s);
	return 0;
}

3. Blocking, callback, polling:

  • Classification of event-related functions:
    - Blocking function: After a function call, it needs to wait for an event to occur before returning, such as functions: scanf, read, accept
    - Non-blocking function: It can return in time after a function call (only mark waiting Event); after the event occurs, it will be passed in a callback mode; for example, when you buy something on Taobao, you place an order, you won’t say that you have been waiting for the item to arrive, you must do other things at this time, only express delivery When the information arrives, you will go to pick up the things you bought! That's called tagging!

  • Blocking and polling:

    • Polling refers to the method of sequentially asking each related device whether it needs service
    • Polling can be used to solve the problem that the blocking function prevents the program from continuing to execute
    • Here we still take the shopping just now as an example. We check every 3 hours to see if the courier has arrived. If not, we will do other things!

There are two ways to solve the efficiency problems caused by blocking functions:

  • way of callback

  • polling method

4. The magical select function:

  • 1. The select() function is used to monitor whether the specified file descriptor generates an event
  • 2. The target event can be detected by polling (the mark changes when the event occurs)
  • 3. Make specific processing according to the event type (eg: read data)
int select(int maxfd,fd_set *readset, fd_set *writeset, fd_set *exceptset,
 const struct timeval *timeout);

The following is the process of using the select() function:
insert image description here
select() related data types and operations:

FD_ZERO(fd_set *fdset);//讲fd_set变量的所有位设置位0

FD_SET(int fd,fd_set *fdset);//讲fd_set中指定需要监听的fd

FD_CLR(int fd , fd_set *fdset); //在fd_set中剔除fd,不再监听

FD_ISSET(int fd, fd_set *fdset); //在fd_set 查看是否包含fd

The following is a practical example of multiplexing:

#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unisted.h>

int main()
{
    
    
	int iofd = 0;
	char s[] = "linux\n";
	fd_set reads = {
    
    0};
	fd_set temps = {
    
    0};
	
	struct timeval timeout = {
    
    0};
	FD_ZERO(&reads);//将fd_set变量的所有位设置位0
	FD_SET(iofd, &reads);//将fd_set中指定需要监听的fd
	
	while(1)
	{
    
    
		int ret = -1;
		temps = reads;//这里为什么这样做,主要是为了避免之前设置的reads标记被select函数覆盖了
		timeout.tv_sec = 0;
		timeout.tv_usec = 50000;
		ret = select(1,&temps,0,0,&timeout);
	
		if(ret >0) //轮询的结果有事情发生
		{
    
    
			len = read(iofd, s ,sizeof(s) - 1);//都输入输出设备中的数据
			s[len] = 0;
			printf("%s\n",s);
		}
		else if(ret ==0)//轮询的结果没有事件发生,这里可以体现出轮询来,因为没有事件,所以走这里
		{
    
    
			static int count = 0;
			usleep(10000);
			count++;
			if(count >100)
			{
    
    
				printf("do something else\n");
				count = 0;
			}
		}
		else//发生了错误
		{
    
    
		}
	}
}

Guess you like

Origin blog.csdn.net/Dada_ping/article/details/128336278