Multi-thread file management method and device, storage medium and electronic equipment

By using a descriptor mapping table to manage the mapping relationship between security descriptors and actual file descriptors in a multi-threaded environment, the problem of low security in file descriptor management is solved, isolation and consistency of resource access are achieved, and the security and stability of applications are improved.

CN120763121AActive Publication Date: 2025-10-10LANGCHAO ELECTRONIC INFORMATION IND CO LTD
View PDF 5 Cites 0 Cited by

Patent Information

Application Number
CN202511295874.9
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-09-11
Publication Date
2025-10-10
Estimated Expiration
2045-09-11

AI Technical Summary

Technical Problem

In a multi-threaded environment, file descriptor management suffers from low security issues, leading to undefined behavior such as data corruption or program crashes. This is especially true in highly concurrent web servers and database management systems, where threads may misuse closed descriptors, causing data corruption or information leakage.

Method used

A descriptor mapping table is introduced to store the mapping relationship between the security descriptor (first descriptor) and the actual file descriptor (second descriptor). The closing instruction is received through the security descriptor, and the mapping relationship is found and deleted to ensure that only the correct resources are closed, preventing descriptor reuse and inconsistent resource status.

Benefits of technology

Significantly reduce the risk of resource conflicts and data corruption, ensure the consistency of file resource status, improve application security and stability, and avoid resource access errors between threads.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120763121A_ABST
    Figure CN120763121A_ABST
Patent Text Reader

Abstract

The invention discloses a multi-thread file management method and device, a storage medium and electronic equipment, and relates to the technical field of file management.The method comprises the steps that a first instruction sent by a first thread is received, the first instruction is used for indicating to close a target file, and the first instruction comprises a first descriptor; a descriptor mapping table is accessed, a second descriptor corresponding to the first descriptor is searched, the second descriptor is used for indicating the target file, and the descriptor mapping table is used for storing the mapping relation between the first descriptor and the second descriptor; and under the condition that the first descriptor exists in the descriptor mapping table, deleting the mapping relationship, and closing the target file based on the second descriptor. The problem that the file descriptor management method in the related technology is low in safety is solved, and the technical effect of improving the program safety is achieved.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present application relates to the field of file management, and in particular to a multi-threaded file management method and device, a storage medium, and an electronic device. Background Art

[0002] In traditional Unix / Linux environments, file descriptors (FDs) are handles that processes use to access files and other I / O resources. This becomes more complex when multiple threads share the same process space and attempt to access the same file descriptor simultaneously. For example, in a highly concurrent web server, multiple threads may need to simultaneously read and write log files or establish network connections with clients. In a database management system, threads may need to simultaneously access multiple data files or index files to execute complex queries and transactions.

[0003] In a multi-threaded environment, file descriptor management in related technologies still faces the following flaws: if one thread closes a file descriptor while other threads are still using it, other threads may continue to attempt to read or write to the closed descriptor, resulting in undefined behavior such as data corruption or program crashes. If a closed file descriptor is reallocated to another file, if the old thread continues to use the old descriptor without noticing the descriptor's closure or reuse, it may write to or read from the wrong file, leading to data corruption or information leakage. This means that the file descriptor management methods in related technologies suffer from low security. Summary of the Invention

[0004] The present application provides a multi-threaded file management method and device, a storage medium, and an electronic device to at least solve the problem of low security of the file descriptor management method in the related art.

[0005] The present application provides a multi-threaded file management method, comprising: receiving a first instruction sent by a first thread, wherein the first instruction is used to instruct to close a target file, and the first instruction includes a first descriptor;

[0006] Accessing a descriptor mapping table to search for a second descriptor corresponding to the first descriptor, wherein the second descriptor is used to indicate a target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor;

[0007] In a case where the first descriptor exists in the descriptor mapping table, the mapping relationship is deleted, and the target file is closed based on the second descriptor.

[0008] The present application also provides a multi-threaded file management device, comprising: a first receiving module, configured to receive a first instruction sent by a first thread, wherein the first instruction is used to instruct to close a target file, and the first instruction includes a first descriptor;

[0009] A search module is used to access a descriptor mapping table to search for a second descriptor corresponding to a first descriptor, wherein the second descriptor is used to indicate a target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor;

[0010] The mapping table adjustment module is used to delete the mapping relationship when the first descriptor exists in the descriptor mapping table, and close the target file based on the second descriptor.

[0011] The present application also provides an electronic device, comprising: a memory for storing a computer program; and a processor for implementing the steps of any of the above-mentioned multi-threaded file management methods when executing the computer program.

[0012] The present application also provides a computer-readable storage medium, in which a computer program is stored. When the computer program is executed by a processor, the steps of any of the above-mentioned multi-threaded file management methods are implemented.

[0013] The present application also provides a computer program product, including a computer program, which implements the steps of any of the above-mentioned multi-threaded file management methods when executed by a processor.

[0014] The present application receives a first instruction sent by a first thread, wherein the first instruction instructs closing a target file and includes a first descriptor. The system then accesses a descriptor mapping table to search for a second descriptor corresponding to the first descriptor, wherein the second descriptor indicates the target file and the descriptor mapping table stores the mapping relationship between the first and second descriptors. If the first descriptor exists in the descriptor mapping table, the mapping relationship is deleted and the target file is closed based on the second descriptor. By introducing the concepts of a first descriptor (i.e., a security descriptor) and a second descriptor (i.e., an actual file descriptor), the system significantly reduces the risk of resource conflicts and data corruption when sharing resources between multiple threads or processes. When a thread issues a close command (the first instruction), the system first searches the descriptor mapping table for the actual file descriptor associated with the security descriptor to ensure that only the correct resource is closed. Upon finding the second descriptor in the descriptor mapping table, the system immediately deletes the mapping relationship between the first and second descriptors. This means that once a resource is closed, the security descriptor is no longer mapped to any system resources, preventing descriptor reuse and preventing threads from misusing closed resources. By querying and updating the descriptor mapping table, the consistency of file resource states is ensured. In a multi-threaded environment, each thread uses a separate security descriptor to reference resources. This helps isolate resource access between threads and avoids errors caused by inconsistent resource states. This addresses the technical issue of low security in current file descriptor management methods, improving application security. BRIEF DESCRIPTION OF THE DRAWINGS

[0015] In order to more clearly illustrate the embodiments of the present application, the following is a brief introduction to the drawings required for use in the embodiments. Obviously, the drawings described below are only some embodiments of the present application. For ordinary technicians in this field, other drawings can be obtained based on these drawings without any creative work.

[0016] Figure 1 is a schematic diagram of a hardware environment of an optional multi-threaded file management method according to an embodiment of the present application;

[0017] Figure 2 is a flowchart of an optional multi-threaded file management method according to an embodiment of the present application;

[0018] Figure 3 is a schematic diagram of an optional safety shutdown process according to an embodiment of the present application;

[0019] Figure 4 is a schematic diagram of an optional safe opening process according to an embodiment of the present application;

[0020] Figure 5 is a schematic diagram of an optional secure writing process according to an embodiment of the present application;

[0021] Figure 6 is a schematic diagram of an optional multi-threaded file management according to an embodiment of the present application;

[0022] Figure 7 is a schematic diagram of another optional multi-threaded file management according to an embodiment of the present application;

[0023] Figure 8 This is a structural block diagram of an optional multi-threaded file management device according to an embodiment of the present application. DETAILED DESCRIPTION

[0024] The following will be combined with the accompanying drawings in the embodiments of this application to clearly and completely describe the technical solutions in the embodiments of this application. Obviously, the embodiments described are only part of the embodiments of this application, not all of them. Based on the embodiments in this application, all other embodiments obtained by ordinary technicians in this field without making creative efforts are within the scope of protection of this application.

[0025] It should be noted that, in the description of this application, the terms "comprises," "includes," or any other variations thereof are intended to cover non-exclusive inclusion, such that a process, method, article, or device comprising a series of elements includes not only those elements, but also other elements not explicitly listed, or elements inherent to such process, method, article, or device. The terms "first," "second," etc., in this application are used to distinguish similar objects, and are not used to describe a particular order or sequence.

[0026] In order to enable those skilled in the art to better understand the present application, the present application is further described in detail below with reference to the accompanying drawings and specific implementation methods.

[0027] According to one aspect of the embodiment of the present application, a multi-threaded file management method is provided. As an optional implementation, the multi-threaded file management method can be applied to, but is not limited to, Figure 1 The multi-threaded file management system in the hardware environment shown in FIG. The multi-threaded file management system may include, but is not limited to, a server 102, a network 104, and a disk array 106. The server 102 runs a target client.

[0028] The server 102 may execute step S102, wherein a first thread in a central processing unit (CPU) in the server 102 generates a first instruction and executes steps S104-S106, accesses a descriptor mapping table, searches for a second descriptor corresponding to the first descriptor, deletes the mapping relationship if the first descriptor exists in the descriptor mapping table, and executes step S108 to close the target file based on the second descriptor.

[0029] It should be noted that the actual application scenario can be in high-concurrency, multi-threaded server systems, especially in those fields with extremely high requirements for file operation security, such as database servers, financial transaction systems, large enterprise application servers, etc.

[0030] For example, when a database server processes multiple concurrent transactions, it frequently reads and writes files on disk. In a multithreaded model, each transaction may be handled by a different thread, and these threads need to share certain file resources. A first instruction is issued by a thread (referred to as the "first thread") to instruct the closing of a target file. The first instruction contains a first descriptor (i.e., the security descriptor safe_fd), which is generated by the security management layer when the file is opened and serves as the front-end interface for file operations.

[0031] After the security management layer receives the first instruction, it executes the step "Accessing the Descriptor Mapping Table." This operation is still performed by the security management layer, and the object of action is the descriptor mapping table. The descriptor mapping table is one of the key data structures maintained by the security management layer. It is used to store the mapping relationship between security descriptors and real descriptors (i.e., the file descriptor real_fd at the operating system level), as well as status entry information. By searching the mapping table for the entry associated with the first descriptor, the security management layer can determine the information of the target file (indicated by the second descriptor). If the first descriptor exists in the mapping table, it indicates that the current close operation is for a valid file descriptor managed by the security management layer.

[0032] Once the security descriptor is confirmed to exist in the descriptor mapping table, this step is also performed by the security management layer, acting on the descriptor mapping table and the operating system kernel. The security management layer first unlocks and removes the entry associated with the first descriptor in the mapping table. This prevents subsequent threads from referencing the closed descriptor when operating on the file. After confirming that no other threads hold a reference to the security descriptor, the security management layer uses the second descriptor (real_fd) to call the operating system's close function to actually close the file. This is the actual resource release operation, which is handled by the operating system kernel.

[0033] Read and write operations on the disk typically occur within the storage subsystem of the server. The disk array 106 can be a hard disk drive, SSD (solid-state drive) or network storage device inside the server (such as storage connected via a SATA, SAS or NVMe interface), or an external storage resource accessed through the network 104, such as a NAS (network attached storage) or SAN (storage area network) device.

[0034] Within a server, disk read / write requests are first generated by the central processing unit (CPU) or an application running on the CPU. When a process or thread needs to read or write a file on disk, it initiates the request by invoking system calls provided by the operating system. These system calls include, but are not limited to, read, write, open, and close, which are essentially a series of instructions executed by the application or thread through the CPU. Once a system call is triggered, the request is passed to the operating system kernel, a core component of the server software architecture responsible for managing hardware resources and providing high-level system services. After receiving the disk read / write request, the kernel further processes it and sends it to the storage device driver, a component of the kernel responsible for communicating with the specific storage hardware, including disks, SSDs, or network storage devices. Upon receiving the request, the storage device driver converts the read / write operation into a command that directly interacts with the storage hardware. These commands are then sent to the storage device via a hardware interface (such as SATA, SAS, or NVMe) to perform the actual data read or write operation. Upon completion of the operation, the storage device returns the result to the driver, which then passes the result or status back to the kernel. The kernel ultimately returns a response to the application or thread that initiated the request.

[0035] The embodiment of the present application provides a multi-threaded file management method. Figure 2 is a flowchart of an optional multi-threaded file management method according to an embodiment of the present application; Figure 2 As shown, the multi-threaded file management method includes:

[0036] Step S202: receiving a first instruction sent by a first thread, wherein the first instruction is used to instruct closing a target file, and the first instruction includes a first descriptor;

[0037] It's important to note that a first instruction refers to an operation request initiated by an application or a thread within the system. Specifically, in this case, it's an instruction to close a target file. In practice, this typically involves calling a function like safe_close, where the parameter contains the security descriptor of the file to be closed. The target file is the specific file being accessed or operated on the system, identified by its corresponding first descriptor (security descriptor).

[0038] The first descriptor is the safe descriptor (safe_fd), which is an additional descriptor layer created by the system for safer management of file descriptors. The value of the safe descriptor is usually much higher than the system's default file descriptor range, to avoid conflicts with system-level descriptors.

[0039] When the system receives a command to close a target file, the command includes a safe descriptor as a parameter. This means that when a thread or process in the system wants to close a file, it does not directly manipulate the system-level file descriptor, but instead uses a higher-level, safer descriptor (the safe descriptor) to convey the closing request. This approach increases the safety and accuracy of the closing operation, as the safe descriptor can better control and manage the life cycle of file descriptors.

[0040] In a multi-threaded or concurrent environment, the safety and reliability of resource management (such as file descriptors) are crucial to avoid problems such as data corruption, resource leaks, or security vulnerabilities. To this end, a file management mechanism based on safe descriptors can be designed. When a thread or process wants to close a file, it sends a closing instruction (the first instruction) that carries a safe descriptor rather than a direct file descriptor. After receiving the closing request, the system will look up the relevant file descriptor mapping table according to the safe descriptor, and then find the actual file descriptor that needs to be closed, thus ensuring that the correct target file is closed.

[0041] The first descriptor starts from a higher value (such as 10000 or higher), which does not overlap with the value range of traditional file descriptors (real_fd or simply fd) in the operating system (usually 0 to FD_SETSIZE, defaulting to 1024, but can be larger in practice), thus ensuring the independence and safety of the two.

[0042] Since the safe descriptor starts from a much higher value than the file descriptor, this design effectively avoids the value overlap between the two. At the operating system level, file descriptor management is usually based on a lower value range, while the safe descriptor is managed independently in the user space, avoiding conflicts between system resource management and user-defined resource management.

[0043] The safe descriptor uses a global atomic counter when it is generated, starting from a large initial value (such as 10000) and incrementing to ensure that each descriptor is unique within the entire system. Even in high-concurrency scenarios, this mechanism prevents two or more threads / processes from obtaining the same descriptor simultaneously, thus avoiding resource confusion and competition.

[0044] Once a security descriptor is used to close a file or resource, the system immediately removes the associated mapping record from the descriptor mapping table. This means that the security descriptor is no longer associated with any actual file descriptor, and its value will not be used again to create a new mapping entry. This measure avoids potential security risks and data corruption caused by descriptor reuse. Because there is no numerical overlap between security descriptors and file descriptors, even if two different operations are ultimately assigned the same file descriptor, their security descriptors will still be different. Therefore, even in the case of file descriptor reuse, the security descriptor can ensure the isolation and security of operations.

[0045] Step S204: accessing a descriptor mapping table to search for a second descriptor corresponding to the first descriptor, wherein the second descriptor is used to indicate a target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor;

[0046] It should be noted that the descriptor mapping table is a data structure maintained in the security management layer that stores the mapping between security descriptors (primary descriptors) and actual file descriptors (secondary descriptors). When a file is opened, an entry is created in the mapping table, which records the actual file descriptor and its associated security descriptor.

[0047] The second descriptor is the actual file descriptor (real_fd), which is allocated by the operating system kernel and used directly for file system calls. In the descriptor mapping table, each security descriptor corresponds to an actual file descriptor.

[0048] After receiving the instruction to close the target file, the system needs to access the descriptor mapping table and find the second descriptor (the actual file descriptor) that matches the first descriptor (the security descriptor). Through this mapping relationship, the system can locate the specific file to be closed and then perform the subsequent closing operation.

[0049] In an optional embodiment, to ensure secure management of file descriptors in a multi-threaded or concurrent environment, each time a file is opened, the system creates a security descriptor and associates it with the actual file descriptor and stores it in a descriptor mapping table. When a file needs to be closed, the system first receives a close request (a first instruction) containing the security descriptor. Following this step, i.e., S204, the system accesses the descriptor mapping table, searches for the mapping entry corresponding to the security descriptor, and then locates the actual file descriptor (the second descriptor). This ensures that the close operation is accurately applied to the target file without affecting other files or resources still in use.

[0050] In an optional embodiment, the descriptor mapping table can be a hash table with a security descriptor as the key and a status entry pointer as the value. The status entry contains information such as the actual file descriptor, reference count, close flag, mutex lock, and condition variable, such as std::unordered_map. Since the descriptor mapping table is a shared resource, multiple threads may access it at the same time, so read-write locks are used to control concurrent access. The read lock allows multiple threads to read the mapping table at the same time, while the write lock ensures exclusivity when modifying the mapping table. The specific locking process will be described in detail later. If the corresponding security descriptor cannot be found in the mapping table, this usually means that the target file descriptor has been closed or has never existed. At this time, an error code such as EBADF should be returned to indicate an illegal file descriptor.

[0051] Step S206: If the first descriptor exists in the descriptor mapping table, the mapping relationship is deleted, and the target file is closed based on the second descriptor.

[0052] It's important to note that when the system successfully finds the corresponding real_fd in the descriptor mapping table using the safe_fd, it confirms the file to be closed. Next, the system removes the mapping from the table to prevent future misuse of the safe_fd or confusion with other operations. The system then performs the actual file closing operation based on the found real_fd, releasing all resources associated with the file.

[0053] In a multi-threaded environment, closing a file is an operation that requires special care, because multiple threads may hold references to the same file at the same time. To ensure the safety of the close operation, when thread A initiates a close instruction, the system will search the descriptor mapping table for real_fd through safe_fd after receiving the instruction. If a mapping is found, the mapping is immediately deleted. This step is to disconnect the safe descriptor from the actual file descriptor to prevent future reuse conflicts. Next, the system will ensure that no other thread references the real_fd before actually closing the file and releasing all related resources. The advantage of doing this is that, on the one hand, it avoids data pollution or security vulnerabilities that may be caused by file descriptor reuse; on the other hand, it ensures that the file is correctly closed in a multi-threaded environment, preventing data corruption and other undefined behaviors.

[0054] In an optional embodiment, after receiving the safe_close instruction, the system first queries the descriptor mapping table through the safe_fd to find the corresponding real_fd. If the real_fd is found in the descriptor mapping table, the system immediately removes this mapping relationship to prevent the safe_fd from being misused for other file operations in the future. Under safe conditions, the system uses the real_fd to execute the real close system call to close the file and release all related resources. After closing the file, the system also needs to clean up the resources in the state entry associated with the real_fd, such as condition variables, mutexes, etc.

[0055] According to the application, a first instruction sent by a first thread is received, where the first instruction is used to indicate closing a target file, and the first instruction includes a first descriptor; a descriptor mapping table is accessed to find a second descriptor corresponding to the first descriptor, where the second descriptor is used to indicate the target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor; and in a case where the first descriptor exists in the descriptor mapping table, the mapping relationship is deleted, and the target file is closed based on the second descriptor. By introducing the concepts of the first descriptor (i.e., a safe descriptor) and the second descriptor (i.e., an actual file descriptor), the risk of resource conflict and data damage can be significantly reduced when resources are shared among multiple threads or between threads. When a thread issues a closing command (the first instruction), the system first finds the actual file descriptor associated with the safe descriptor in the descriptor mapping table to ensure that only the correct resource is closed. After the second descriptor is found in the descriptor mapping table, the mapping relationship between the first descriptor and the second descriptor is immediately deleted. This means that once the resource is closed, the safe descriptor will no longer be mapped to any system resource, preventing the reuse of the descriptor and avoiding the misuse of the closed resource by a thread. Through the query and update actions of the descriptor mapping table, the state consistency of the file resource is ensured. In a multi-threaded environment, each thread uses an independent safe descriptor to reference the resource, which helps to isolate resource access between threads and avoids errors caused by inconsistent resource states between threads. Therefore, the technical problem of low safety of the current file descriptor management method can be solved, and the technical effect of improving the safety of the application program is achieved.

[0056] In an optional embodiment, closing the target file based on the second descriptor includes: reading a data space corresponding to the first descriptor, where the data space is used to indicate the state of the first descriptor; determining a reference number included in the data space, where the reference number is used to indicate the number of threads currently accessing the target file; and in a case where the reference number is a preset number, closing the target file based on the second descriptor.

[0057] It should be noted that the data space refers to the status entry structure, which is a structure containing information about the file descriptor status. It stores key information associated with the first descriptor (i.e., the security descriptor) and is used to indicate and manage the status of the file descriptor.

[0058] The reference count is a key field in the data space that tracks how many threads or processes are currently using the file descriptor associated with the status entry. Managing the reference count is crucial for ensuring safe closing of the target file. The preset count specifically refers to a specific value that the reference count must reach. During safe closing of the target file, the actual file close occurs only when the reference count drops to zero (the preset count), ensuring that no other threads or processes are still using the file descriptor.

[0059] It should be noted that the data space, namely the status entry structure (fd_entry_t), can contain the following key data:

[0060] real_fd: The actual file descriptor, allocated by the operating system kernel.

[0061] closed: Close flag, used to indicate whether the file descriptor has been marked as closed.

[0062] ref_count: An atomic reference count that tracks the number of threads or processes that are using this file descriptor.

[0063] lock: Mutex lock (pthread_mutex_t), which provides exclusive access control at the state entry level.

[0064] cond: Condition variable (pthread_cond_t), allows waiting for the reference count to drop to a preset number of times.

[0065] creator_pid and creator_tid: Record the process and thread ID that created the file descriptor, which can be used for debugging and auditing.

[0066] create_time: creation timestamp, used to calculate the life cycle of the file descriptor.

[0067] When a thread attempts to close a file identified by a security descriptor, the system accesses the state entry (that is, the data space) corresponding to the security descriptor. The system checks the reference count in the data space. If the reference count is equal to a preset number—usually zero—it means that no other threads or processes are accessing the file, so it is safe to perform a close operation based on the real file descriptor (real_fd).

[0068] In an optional embodiment, the security descriptor is used as an index to access the descriptor mapping table to obtain the corresponding status entry. The value of the ref_count field is obtained from the status entry, which will indicate how many threads or processes are currently using the file descriptor. If the reference count is greater than a preset number (i.e., zero), the thread will wait until the reference count drops to a preset number. This can be achieved through a condition variable, which is set to wait until the ref_count drops to zero. Once the reference count reaches the preset number, the system will execute a real close system call, close the file using real_fd, and release all resources associated with the file descriptor. Finally, the status entry will be cleaned up, including releasing resources such as mutexes and condition variables contained in the entry. When handling reference counts, atomic operations (such as atomic_fetch_add and atomic_fetch_sub) are used to ensure that the increase and decrease operations of the reference count are thread-safe.

[0069] Through the above-described implementation of the present application, when a safe close instruction is received, the system checks whether the reference count in the status entry is zero. If not, it waits until the reference count reaches zero and sets a close flag during this period. Once the reference count reaches zero, the system actually closes the file and cleans up the resources associated with the status entry. This mechanism based on atomic operations and conditional variables ensures the security and consistency of descriptor closing, especially in a multi-threaded concurrent environment, avoiding race conditions in the close operation and ensuring thread safety of resource management and uniqueness of descriptors.

[0070] In an optional embodiment, before determining the number of references included in the data space, the method includes: setting the data space corresponding to the first descriptor to a first locked state, wherein the first locked state is used to indicate that the data space is prohibited from access by at least one second thread, which is not the first thread; setting a close indication bit included in the data space to a first preset value, wherein the first preset value is used to indicate that the first descriptor is in a closed state;

[0071] After closing the target file based on the second descriptor, the method includes setting the data space corresponding to the first descriptor to a first unlocked state, wherein the first unlocked state is used to indicate that the data space is accessible to the first thread and at least one second thread.

[0072] The first lock state can be the exclusive lock state set in the status entry, indicating that the data space is not accessible to threads other than the current operating thread (the first thread) to ensure data consistency and integrity. The first preset value is the flag value of the descriptor closed state, typically 1 or true, which is used to mark the file descriptor in the status entry as closed.

[0073] The first unlocked state may indicate that when the file descriptor is securely closed and all references are released, the mutex state of the data space changes from locked to unlocked, indicating that other threads can access and use the data space again. However, it should be noted that subsequent access may return an error because the file has been closed.

[0074] When a thread (the first thread) decides to close a file descriptor, it first sets the descriptor's corresponding data space (the status entry) to a locked state. This prevents other threads (the second thread) from modifying or accessing the data space while the close operation is in progress. Subsequently, the close indicator bit in the status entry is set to a first preset value, indicating that the file descriptor is in the process of being closed.

[0075] Once the actual file descriptor (secondary descriptor) is closed and all references to the file descriptor are released, the data space lock is released and becomes unlocked, which means the data space is open to all threads again, but because the file descriptor has been marked as closed, any subsequent access attempts will be considered illegal and may return an error.

[0076] In an optional embodiment, in a multi-threaded environment, to ensure the safety of file descriptor closing operations, when a thread decides to close a file descriptor, it first locks the status entry. This is achieved by setting a mutex (e.g., pthread_mutex_t) to a locked state (a first locked state), ensuring that the status entry is not modified by other threads during the file closing process. At the same time, the close indicator bit in the status entry is set to a first preset value (e.g., 1), indicating that the file descriptor is in a closed state. Once the file is actually closed and all reference counts are reset to zero, the status entry is unlocked (set to the first unlocked state). This does not mean that the file descriptor can be used again, but rather that the data space can be read by other threads to check its status, such as by checking the close indicator bit.

[0077] In an optional embodiment, before closing the file descriptor, a mutex lock in the status entry is acquired to prevent other threads from accessing the file. The close indicator bit in the status entry is set to a first preset value, marking the file descriptor as closed. A condition variable is used to wait until the reference count in the status entry reaches 0, ensuring that all threads have released their references to the file. Based on the actual file descriptor, a system call close is called to actually close the file. After the file close operation is complete and all resources are cleaned up, the previously acquired mutex lock is released, making the status entry visible to all threads again.

[0078] With the above embodiments of the present application, the safe_close function first acquires a global write lock to process the mapping table, looking up the real_fd corresponding to the safe_fd. If a mapping relationship is found, the mapping is removed, and the safe close procedure continues. Before the actual close operation, the function locks the state entry, sets the close indication bit to true, and waits for the reference count to go to zero. Once all references are released, the function calls the system call close to close the file, and upon completion of the operation, it unlocks the state entry and then releases all associated resources. If no entry is found in the mapping table, the system close function is called directly, but an error can be returned, indicating that the safe_fd is invalid or the file is already closed. In this way, the system can ensure that the close operation of the file descriptor is safe in a multi-threaded environment, and the management of the state entry is thread-safe.

[0079] In optional embodiments, before accessing the descriptor mapping table, the system sets the descriptor mapping table to a second locked state, where the second locked state indicates that the descriptor mapping table is inaccessible to at least one second thread. After deleting the mapping relationship, the system sets the descriptor mapping table to a second unlocked state, where the second unlocked state indicates that the descriptor mapping table is accessible to the first thread and the at least one second thread.

[0080] It should be noted that the second locked state can be a state in which the descriptor mapping table is in a state in which it is not allowed to be accessed or modified by any thread (at least one second thread) other than the thread currently performing the locking operation (i.e., the first thread). The second unlocked state can be a state in which the descriptor mapping table is in a state in which it is allowed to be accessed and modified by all threads, including the first thread and any other threads (at least one second thread).

[0081] Before accessing the descriptor mapping table, the system sets the descriptor mapping table to a second locked state, which ensures that the mapping table cannot be accessed by other threads, thereby avoiding concurrent conflicts that can occur when reading or modifying the mapping table. After deleting the mapping relationship in the descriptor mapping table, the system sets the descriptor mapping table back to the second unlocked state, re-enabling all threads (including the first and at least one second threads) to access and modify the mapping table, ensuring resource sharing and synchronization in a multi-threaded environment.

[0082] In multithreaded programs, access to shared resources must be properly synchronized to avoid race conditions and data inconsistencies. As a global data structure, the descriptor map requires locking to protect access and modification to ensure thread safety. The descriptor map uses a read-write lock (pthread_rwlock) to access and modify the descriptor map. This allows multiple threads to access the map concurrently (read state), but requires exclusive access to modify the map (e.g., insert or delete).

[0083] In an optional embodiment, before accessing the descriptor mapping table to modify it (e.g., to delete a mapping relationship), the system acquires the descriptor mapping table's write lock (pthread_rwlock_wrlock) and sets the mapping table to a second locked state, preventing any other threads from accessing or modifying it until the lock is released. After the write lock is acquired, the mapping table is in the second locked state, making it safe to delete the mapping relationship. After the modification operation is complete, the system releases the write lock (pthread_rwlock_unlock), setting the descriptor mapping table back to the second unlocked state, allowing other threads (including the first and at least one second thread) to access and modify the mapping table again.

[0084] For example, thread A first acquires the write lock on the global mapping table using pthread_rwlock_wrlock. This sets the descriptor mapping table to the second locked state, prohibiting any other threads from accessing it. Thread A then searches the mapping table for the security descriptor safe_fd=10001 and, if it exists, deletes it. Finally, thread A releases the write lock using pthread_rwlock_unlock, setting the descriptor mapping table back to the second unlocked state and allowing other threads to continue accessing the mapping table.

[0085] Through the above-mentioned implementation of the present application, the security of access and modification operations of the descriptor mapping table in a multi-threaded concurrent environment is ensured through a global lock mechanism, which effectively avoids the occurrence of data inconsistency and race conditions, and improves the security management of file descriptors and the overall stability of the multi-threaded system.

[0086] It should be noted that the descriptor mapping table is a global mapping table that stores all security descriptors and their corresponding status entries. These status entries contain information such as the actual file descriptor, reference count, and closed status.

[0087] The static pthread_rwlock_t global_table_lock is a read-write lock that protects access to the global mapping table, ensuring that both read and write operations (such as inserts, searches, and removes) are thread-safe in a concurrent environment. This lock allows multiple threads to read simultaneously, but only one thread to write. This design improves the performance and responsiveness of multithreaded applications.

[0088] static std::unordered_map<int,fd_entry_t> fd_table is an unordered hash map using the std::unordered_map container from the C++ Standard Library. It uses security descriptors as keys and pointers to status entry structures as values. This data structure provides fast lookup and insertion capabilities, making it ideal for dynamically managing the mapping relationships of large numbers of file descriptors, especially in highly concurrent environments. It offers average constant-time lookup performance, making it ideal for implementing fast descriptor mapping lookups. In this mapping table, safe_fd is used as the key and a pointer to an fd_entry_t (status entry) is used as the value. This design enables the system to quickly locate the status information of the actual file descriptor corresponding to a given security descriptor, enabling efficient interception and verification of file operations.

[0089] static atomic_uint next_safe_fd=10000 is an atomic variable used to generate the next available security descriptor. Atomic variables ensure that the generation of security descriptors in a high-concurrency environment is thread-safe and avoids numerical conflicts. The starting value of the security descriptor is usually set to a value much larger than the system default descriptor range (such as 10000). This can effectively distinguish system-level file descriptors from user-level security descriptor space to prevent misoperation and reuse conflicts. next_safe_fd is used to generate the next available security descriptor. Its starting value is set to 10000, which is much higher than the system default descriptor range to avoid conflicts with system-level descriptors. Each time a new security descriptor is generated, the value of next_safe_fd is atomically increased to ensure that each security descriptor generated is globally unique.

[0090] Example 1:

[0091] Figure 3 is a schematic diagram of an optional safety shutdown process according to an embodiment of the present application; Figure 3As shown, after the first thread 302 completes access to the target file, it can execute step S302 to send a first instruction to the security management layer 304. After receiving the first instruction, the security management layer 304 can execute steps S304-S306 to access the descriptor mapping table and, if conditions are met, delete the mapping relationship of the first descriptor. Then, it executes step S308 to send a close instruction to the kernel layer 306. The first instruction can be, for example, safe_close(10001), and the close instruction can be sys_close(5). 10001 can be the first descriptor, and 5 can be the second descriptor.

[0092] Specifically, the application has successfully opened and used a file, obtaining a security descriptor safe_fd. A global status tracking table has been created and maintained, recording the status of all security descriptors, including reference counts, closed flags, creator information, etc.

[0093] Suppose thread ThreadA has completed its file operation and decides to close the file. ThreadA calls the safe close interface provided by the security management layer, such as the safe_close function, passing the security descriptor safe_fd. Upon receiving ThreadA's close request, the security management layer begins executing the safe close protocol. The security management layer searches the global descriptor map for the real file descriptor, real_fd, associated with safe_fd. The security management layer checks the status of safe_fd to determine if it has been closed. If safe_fd is marked closed, it returns an error message to ThreadA. If the status of safe_fd indicates that the file has not been closed, the security management layer sets the descriptor's status to "closing in progress." Simultaneously, it uses an atomic operation to decrement the descriptor's reference count. The security management layer monitors the reference count using a condition variable. If the reference count is greater than zero, it indicates that other threads still hold the descriptor, and the system waits until all threads release their references to safe_fd. Once all references are released, meaning the reference count reaches zero, the security management layer removes the entry associated with safe_fd from the global map to prevent future multiple closes. The security management layer calls the system-level close system call to close the real_fd associated with safe_fd, freeing operating system resources. After real_fd is successfully closed, the security management layer destroys the state entry associated with safe_fd, freeing the memory resources used for state management. Finally, the security management layer notifies ThreadA, which issued the close request, that the file descriptor safe_fd has been safely closed. ThreadA can then continue with subsequent operations or terminate the thread.

[0094] If safe_fd does not exist in the global mapping table (for example, it has been closed or has never been opened), the safety management layer will directly return an error code such as EBADF (Bad File Descriptor) to the application without performing any further closing operations or releasing resources. While waiting for the reference count to return to zero, if the waiting time exceeds the preset timeout threshold, the safety management layer will trigger the timeout handling mechanism, log the event, and attempt to take recovery measures, such as forcibly closing real_fd, to avoid possible deadlock.

[0095] The safe close process ensures the security and consistency of file descriptor operations in a multi-threaded environment, preventing accidental data corruption, resource conflicts, and security vulnerabilities caused by concurrent operations. This process implements descriptor lifecycle management through the security descriptor management system. Specifically, through the use of reference counting and condition variables, it ensures that all threads have properly released their references before the descriptor is actually closed, thereby improving the stability and security of server applications.

[0096] In an optional embodiment, before receiving a first instruction sent by a first thread, it includes: receiving a second instruction sent by a third thread, wherein the second instruction is used to instruct to open a target file, wherein the third thread and the first thread belong to the same process space; generating a first descriptor and a second descriptor; establishing a mapping relationship between the first descriptor and the second descriptor; accessing a descriptor mapping table, and storing the mapping relationship in the descriptor mapping table.

[0097] It should be noted that the second instruction is issued by a third thread (usually another thread in the process space to which the first thread belongs) to open a new file or resource, thereby generating a new file descriptor. A process space refers to the address space within a process, where multiple threads share memory resources and descriptor mapping tables.

[0098] Before receiving the first instruction from the first thread, the system may first receive the second instruction from the third thread. This third thread actually belongs to the same process space; that is, it could be another thread within the first thread, or a thread within the same process. The second instruction's goal is to open the target file. This action causes the system to generate a first descriptor and a second descriptor: a security descriptor and an actual file descriptor. The system then establishes a mapping between the first and second descriptors to ensure their relevance. Finally, the system accesses the descriptor mapping table and stores the mapping there.

[0099] In an optional embodiment, when a third thread requests to open a file, the system receives and parses the open instruction, which typically includes parameters such as the specified file name and opening mode. The system calls a kernel interface, such as sys_open, to request the generation of an actual file descriptor (real_fd). The system uses the atomic variable next_safe_fd to generate a safe descriptor (safe_fd), ensuring that its value is significantly larger than the system's default descriptor range to prevent overlap. A status entry structure is created to record the real_fd, an initial reference count (typically 1), a close flag (initially unclosed), and necessary locking mechanisms and conditional variables. The write lock of the global mapping table is acquired, and the newly created status entry (containing the real_fd and related status information) is mapped to the safe_fd and stored in the descriptor mapping table. After the write lock is released, the mapping relationship can be safely used in a multi-threaded environment. The generated safe descriptor (safe_fd) is returned to the third thread for subsequent file operations.

[0100] Through the above-described implementation of the present application, when a thread issues a file open instruction, the system generates a security descriptor and an actual file descriptor, creates a status entry, and then securely establishes a mapping between the two in a global descriptor mapping table. This ensures the security and consistency of file descriptor management and operations in a multi-threaded environment, providing a reliable infrastructure for subsequent file read, write, and close operations.

[0101] In an optional embodiment, before accessing the descriptor mapping table, the method includes: setting the descriptor mapping table to a third locking state, wherein the third locking state is used to indicate that the descriptor mapping table is prohibited from being accessed by at least one fourth thread, where the fourth thread is not the third thread;

[0102] After storing the mapping relationship in the descriptor mapping table, the method includes setting the descriptor mapping table to a third unlocked state, wherein the third unlocked state is used to indicate that the descriptor mapping table can be accessed by the third thread and at least one fourth thread.

[0103] It should be noted that the third locking state may be that the descriptor mapping table is in a locking mode, in which case no other thread (at least one fourth thread) other than the current operating thread (third thread) is allowed to access or modify it, thereby ensuring data integrity and consistency.

[0104] The fourth thread refers to any thread other than the thread that is performing a specific operation (such as storing or deleting a mapping relationship) that may attempt to access the descriptor mapping table at the same time.

[0105] The third unlocked state may be a state of the descriptor mapping table that allows all threads, including the current operating thread (the third thread) and any other threads (at least one fourth thread), to access and modify the mapping table, thereby restoring normal concurrent operation capabilities.

[0106] Before performing any operation that requires access to the descriptor mapping table, such as storing or deleting a mapping, the system sets the descriptor mapping table to the third locked state to ensure that the mapping table cannot be accessed or modified by other threads (the fourth thread) while the critical operation is in progress. Only after this step is completed can the descriptor mapping table be read or written. Once the storage or deletion operation of the mapping relationship is completed, the system sets the descriptor mapping table back to the third unlocked state, restoring access to the mapping table to all threads while maintaining data consistency and thread safety.

[0107] To ensure secure access and modification of the descriptor mapping table in a multithreaded environment, a read-write lock (pthread_rwlock) is used to control access to the mapping table. This read-write lock allows multiple threads to access the mapping table during read operations, but only allows a single thread to acquire the write lock for exclusive access during write operations (such as inserting or deleting mapping relationships). Therefore, before each access to the descriptor mapping table, the system acquires the write lock and sets the mapping table to the third locked state. Upon completion of the mapping table modification operation, the system releases the write lock, returning the mapping table to the third unlocked state, allowing other threads to continue accessing the mapping table.

[0108] In an optional embodiment, before performing any operation that requires modifying the descriptor mapping table (such as storing or deleting mapping relationships), a global write lock is first acquired using pthread_rwlock_wrlock, setting the descriptor mapping table to the third locked state to ensure that no other threads can access or modify the mapping table during the operation. After acquiring the lock, the descriptor mapping table is in the third locked state, at which point operations that modify the mapping table can be safely performed, such as inserting new entries, storing mapping relationships in the mapping table, or removing closed descriptor entries from the mapping table. After completing the mapping table modification operation, the previously acquired write lock is released using pthread_rwlock_unlock, setting the descriptor mapping table back to the third unlocked state, allowing all threads, including the third thread and all other threads, to re-access the mapping table.

[0109] Through the above-described implementation of the present application, before inserting or deleting a mapping relationship, the safe_descriptor_operation function acquires a global write lock through pthread_rwlock_wrlock, sets the descriptor mapping table to the third locked state, and blocks access by other threads. After completing the mapping table operation, the write lock is released through pthread_rwlock_unlock, restoring the mapping table to the third unlocked state and allowing all threads to access the mapping table again. This method ensures the thread safety and data consistency of the descriptor mapping table in a multi-threaded environment and is an important component of the present invention for implementing file descriptor security management.

[0110] Example 2:

[0111] Figure 4 is a schematic diagram of an optional safe opening process according to an embodiment of the present application; Figure 4 As shown, if the third thread 402 in the system wishes to open a file, it can execute step S402 to send a second instruction to the security management layer 304. The security management layer 304 can execute step S404 to send an open instruction to the kernel layer 306. The second instruction can be safe_open("file.txt"), which carries information indicating the target file name, such as the target file name. The open instruction can be sys_open("file.txt"). After the kernel layer 306 generates a second descriptor, it executes step S406 to send the second descriptor to the security management layer 304. The security management layer 304 can execute steps S408 and S410 to generate a first descriptor and establish a mapping relationship between the first descriptor and the second descriptor. Thereafter, step S412 is executed to send the first descriptor to the third thread 402.

[0112] Specifically, an application is launched on a server, perhaps a web server, database management system, or other high-performance server software. At this point, the application does not directly interact with the operating system kernel for file operations, but instead uses a wrapper security library interface. Suppose a thread in the application (called thread A) plans to open a file for read or write operations. It sends a file open request to the security management layer. This request includes the file path, access mode (e.g., read-only, read-write), and other necessary parameters.

[0113] Upon receiving the request from thread A, the security manager first performs a series of pre-processing steps, including verifying that thread A has the authority to perform such operations and ensuring that the request is properly formatted. After pre-processing, the security manager invokes the open system call of the operating system kernel. This step is handled by the kernel, which allocates a real file descriptor (real_fd) within the standard system descriptor space (e.g., 0-1024) and associates it with the opened file.

[0114] Upon the kernel's return of real_fd, the security manager immediately generates a unique safe descriptor (safe_fd) from a predetermined safe descriptor space (e.g., starting from 10000). This safe descriptor is used in place of the real descriptor to isolate and protect the management of file descriptors. Next, the security manager creates a state entry to track the status of the real_fd associated with safe_fd. The state entry contains critical information, such as the real_fd value, a close flag (initially set to unclosed), a reference count (initialized to 0), a thread mutex, a condition variable, the creator's PID and TID, and a creation timestamp. The security manager then associates the generated safe_fd with its corresponding state entry and stores them through a global mapping table. This mapping table maintains a one-to-one relationship between safe_fd and state entries, ensuring that each safe descriptor has a clear state tracking. Before allocating safe_fd in the mapping table, the security manager performs an atomic check to ensure that no other thread is applying for the same or similar safe_fd. If the check passes, safe_fd is officially allocated to thread A and inserted into the mapping table, otherwise, it attempts to generate a new safe descriptor until successful allocation. Using a global write lock, the security manager updates its maintained mapping table by adding a record pointing from safe_fd to the state entry. In this way, in subsequent file operations, threads can quickly access the associated state entry and real descriptor through the safe descriptor.

[0115] Once the mapping relationship is established, the security management layer will release the global write lock and return safe_fd to thread A. Thread A can now use this security descriptor to make file system calls, such as reading and writing, without worrying about resource conflicts or data corruption with other threads. Before actually performing file read and write operations, all file system calls of thread A will be intercepted by the security library. The security library layer will perform a pre-verification on safe_fd, check the close flag and reference count in its status entry, and ensure the validity and security of the file descriptor. If the safe_fd verification passes, the security management layer will call the kernel's system call to perform the actual file operation. Whether reading, writing or other operations, the reference count of the status entry will be increased before each operation, and the reference count will be reduced after the operation is completed, so as to monitor and control the use of the descriptor.

[0116] The entire secure open process emphasizes the core role of the security management layer in isolating the descriptor space, maintaining status entries, and performing atomic operations. By generating security descriptors, creating status entries, and updating the global mapping table, thread A is guaranteed to safely interact with the specific file while preventing other threads from accidentally accessing or modifying this resource. This significantly improves the security and reliability of file descriptor management in multi-threaded environments.

[0117] It should be noted that when a process or thread first obtains a file descriptor (system_fd or simply fd) through a system call such as open, the next step is to generate a security descriptor (safe_fd) and create a status entry (i.e., data space) based on it to track and manage the security status of the file descriptor. The process of generating the security descriptor and status entry and inserting them into the mapping table is multi-thread safe to avoid descriptor reuse conflicts and ensure the uniqueness of each pair of system_fd and safe_fd mappings.

[0118] Each time a system_fd is requested, the application calls an internal function to generate a safe_fd. The starting value of this safe_fd is set to 10000, which is much higher than the system's default descriptor range (0-1023) to provide an isolated descriptor space. After generating the safe_fd, the application creates a status entry, which contains information such as the system_fd, a reference count, and a closed status flag for subsequent file operation interception and verification. Once the entry is created, it is inserted into the global mapping table (i.e., the descriptor mapping table) with the safe_fd as the key and the entry pointer as the value. This allows subsequent file operations to index the mapping table using the safe_fd and find the corresponding entry for status verification.

[0119] To avoid safe_fd reuse conflict that might occur in high concurrency scenarios, after applying for a safe_fd, it is first checked whether it already exists in the global mapping table. If the safe_fd already exists, it means that the safe descriptor has been used, at which time the system will reapply for a new safe_fd until an unused safe_fd is found, thus ensuring the uniqueness of each safe_fd.

[0120] To avoid excessive attempts and checks when applying for a safe_fd, a limit on the number of attempts is introduced. The specific strategy is as follows: when the application attempts to generate a safe_fd, the number of application attempts will be limited, for example, set to 100 times. If an available safe_fd is not found within 100 attempts, it means that the global mapping table may be full or the system is in an abnormal state, and further processing measures need to be taken. To further optimize the application process, the application uses a penalty mechanism, that is, after the initial attempt fails, the next time the safe_fd is applied, the value increased from the safe descriptor starting point (10000) will gradually increase. For example, after the first failure, increase by 1, after the second failure, increase by 10, after the third failure, increase by 100, and so on. This incremental increment can prevent excessive attempts on adjacent values in the descriptor space, reduce conflicts in the application process, and improve application efficiency.

[0121] In an optional embodiment, assuming that the thread ThreadOmega attempts to generate a safe descriptor safe_fd, the thread first obtains a system_fd=4 through a system call. Then, the thread calls the internal safe_fd_generation function, and the execution flow of the function is as follows:

[0122] The safe_fd_generation function attempts to generate a safe_fd. It first checks next_safe_fd. Assuming the current value is 10000, safe_fd = 10000 becomes a candidate. The function then checks the global mapping table. If safe_fd = 10000 already exists, the safe_fd request is considered unsuccessful. After the first failed request, next_safe_fd is adjusted to 10001 (i.e., 10000 + 1). It then attempts to generate a safe_fd again. If safe_fd = 10001 also already exists, next_safe_fd is adjusted to 10011 (i.e., 10001 + 10), and so on, until an unmapped safe_fd is found. Once a new, unused safe_fd is identified, the safe_fd_generation function creates a state entry and initializes its fields, such as setting the real_fd field to system_fd = 4, closed to false, and ref_count to 1. Finally, the entry will be inserted into the global mapping table with safe_fd as the key and the address of the entry as the value.

[0123] In an optional embodiment, after storing the mapping relationship in the descriptor mapping table, it includes: receiving a third instruction sent by the fifth thread, wherein the third instruction is used to instruct reading data from the target file or writing data to the target file, the third instruction includes a first descriptor, and the fifth thread and the first thread belong to the same process space; accessing the descriptor mapping table to find the second descriptor corresponding to the first descriptor; if the first descriptor exists in the descriptor mapping table, reading the data space corresponding to the first descriptor, and adding one to the number of references included in the data space; performing the read or write operation indicated by the third instruction on the target file; and reducing one to the number of references included in the data space.

[0124] It should be noted that the third instruction refers to a request to read or write a file, such as one issued through the safe_read or safe_write functions, and includes a security descriptor (safe_fd) as a parameter. The fifth thread is a thread in the same process space as the first thread (possibly the thread that issued the close instruction), and it sends the third instruction to perform the file operation.

[0125] Before performing a file operation (such as a read or write), the fifth thread sends the third instruction and passes the included security descriptor (safe_fd) to the system. The system then accesses the descriptor mapping table to find the actual file descriptor (real_fd) corresponding to safe_fd. If the first descriptor exists in the mapping table, the system reads the status entry corresponding to that descriptor and increments the reference count in the status entry to ensure the safety of the operation. After the file operation is completed, the system decrements the reference count. When the reference count reaches zero, it indicates that all operations on the file have ended and the file can be safely closed.

[0126] In an optional embodiment, a mechanism for secure access and operation of file descriptors in a multi-threaded environment. When the fifth thread needs to read or write a target file, it uses a security descriptor (first descriptor) to initiate a request. The system accesses the descriptor mapping table to confirm whether there is an actual file descriptor (second descriptor) associated with the security descriptor. If so, the system increases the reference count in the descriptor status entry through atomic operations to ensure that the current operation is thread-safe. After the file operation is completed, the reference count will be atomically decremented by one to track the usage status of the descriptor and ensure that the descriptor can be safely closed after all references are completed, preventing descriptor reuse conflicts and the use of closed descriptors.

[0127] The fifth thread sends a read or write request containing a safe_fd. The system accesses the descriptor mapping table, searching for the real_fd and status entries corresponding to the safe_fd. If a mapping exists, the system locks the status entry (using a mutex) and atomically increments the reference count. The actual read or write operation is performed using the real_fd, while the safe_fd is only used for mapping and status verification. After the operation is complete, the reference count is decremented. If the reference count reaches zero and the descriptor has been closed, the resources associated with the descriptor can be released.

[0128] Through the above-described embodiments of the present application, secure read operations on file descriptors are implemented in a multi-threaded environment using security descriptors and a descriptor mapping table, combined with reference counting and locking mechanisms. When processing write operations, the process is essentially the same, except that the underlying system function called is changed from read to write. This mechanism ensures the security, consistency, and correctness of file descriptors in a multi-threaded environment, preventing errors and data corruption that may occur during concurrent multi-threaded operations.

[0129] In an optional embodiment, the reference count of the data space is incremented by one, including: setting the data space corresponding to the first descriptor to a fourth lock state, wherein the fourth lock state is used to indicate that the data space is prohibited to be accessed by at least one sixth thread, the sixth thread being a non-fifth thread; incrementing the reference count of the data space by one; and setting the data space corresponding to the first descriptor to a fourth unlock state, wherein the fourth unlock state is used to indicate that the data space is accessible by the fifth thread and the at least one sixth thread.

[0130] The reference count of the data space is decremented by one, including: setting the data space corresponding to the first descriptor to a fourth lock state; decrementing the reference count of the data space by one; and setting the data space corresponding to the first descriptor to a fourth unlock state.

[0131] It should be noted that the fourth lock state is used to indicate that the current thread (the fifth thread) is modifying the reference count in the data space, and at this time the data space is not allowed to be accessed or modified by the sixth thread (any thread other than the fifth thread), so as to ensure the atomicity and integrity of the operation.

[0132] The fifth thread can be a thread that is performing the reference count incrementing or decrementing operation, and the fifth thread herein actually refers to the current thread that invokes the safe file operation interface. The sixth thread refers to a thread other than the fifth thread that is not performing the reference count operation.

[0133] When performing file read / write operations and the like, the system increases the reference count by locking the data space, which ensures that the modification of the reference count is not disturbed by other threads, thereby maintaining the consistency of the data. Similarly, when the operation is completed and the reference count needs to be reduced, the system also locks the data space to prevent multiple threads from modifying the reference count at the same time, which can cause data confusion.

[0134] When locking the data space, the system sets the data space to the fourth lock state, allowing only the current operation thread (the fifth thread) to access and modify the reference count, effectively preventing interference from other threads (the sixth thread). After modifying the reference count, the system restores the data space to the fourth unlock state, allowing other threads to access the data space again and restoring normal concurrent operation.

[0135] In the optional embodiment, taking a safe read operation as an example, when a thread (the fifth thread) attempts to read a file through a safe descriptor safe_fd=10001, the system first increases the reference count of 10001 by calling increment_reference_count(10001). The system first acquires the mutex corresponding to safe_fd=10001, and sets the data space to the fourth locked state. In the locked state, the system checks and atomically increases the reference count. This operation ensures that the reference count will not be incorrect even if multiple threads attempt to read at the same time. After the reference count operation is completed, the system releases the mutex and sets the data space to the fourth unlocked state. This allows other threads to also perform reference count checking and modification. When the read operation is completed, the system calls decrement_reference_count(10001) to decrease the reference count, and the steps involved are basically the same but in the opposite direction, i.e., from the fourth locked state to the fourth unlocked state, atomically decreasing the reference count, and possibly performing additional cleanup work when the reference count is zero.

[0136] Through the above embodiments of the present application, the atomic operation of the reference count in the file descriptor state entry can be ensured in a multi-threaded environment, preventing data race and inconsistency problems, and ensuring the safety and stability of the file descriptor and its corresponding operations. In addition, by locking and unlocking before and after the reference count operation, the order and synchronization of multi-threaded access are effectively controlled, improving the overall performance and reliability of the system.

[0137] In the optional embodiment, after accessing the descriptor mapping table and finding the second descriptor corresponding to the first descriptor, the method further includes: returning first prompt information in a case where the first descriptor does not exist in the descriptor mapping table, wherein the first prompt information is used to indicate that the first descriptor is unavailable.

[0138] Setting the data space corresponding to the first descriptor to the fourth locked state includes: determining a value of a close indication bit included in the data space; and returning second prompt information in a case where the value of the close indication bit is a first preset value, wherein the second prompt information is used to indicate that the first descriptor is unavailable.

[0139] It should be noted that the first prompt information is an error message generated and returned by the system when the corresponding first descriptor cannot be found in the descriptor mapping table. The close indication bit can be a field in the data space (state entry) and is used to indicate that the file associated with the first descriptor has been closed. The first preset value usually represents the closed state, for example, the number 1, which means that the file descriptor has been marked as closed. The second prompt information is another error message returned by the system if the value of the close indication bit is the first preset value, indicating that the first descriptor is unavailable for operation.

[0140] Before executing the file descriptor close operation, the system needs to find the corresponding first descriptor in the descriptor mapping table. If the descriptor is not in the mapping table, the system will return a first prompt message, which is usually an error code such as EBADF, indicating that the descriptor is invalid or has expired. If the descriptor exists, the next step is to check the close indicator bit in its data space. If the value of the close indicator bit is the first preset value, that is, the file descriptor has been marked as closed, the system will return a second prompt message, which is also an error indication, indicating that the descriptor can no longer be accessed during the closing process.

[0141] To ensure that file descriptors are closed correctly in a multi-threaded environment, the system uses a multi-level locking and status checking mechanism. First, the system attempts to find the entry corresponding to the security descriptor in the descriptor mapping table. If it is not found, it means that the descriptor may have been closed by a previous operation or has never been effectively generated, so the system immediately returns an error. If the entry is found, the system needs to further verify the status of the close indicator bit in the entry to confirm whether the security descriptor has been marked as closed. To ensure the integrity of the data space during this process, the system sets the data space to the fourth lock state in the preparation stage of the close operation. This is achieved by locking resources in the state entry (such as a mutex lock) to ensure that no other threads can read or modify it during the close operation, thereby avoiding data races and inconsistencies.

[0142] In an optional embodiment, before attempting to close a file descriptor, the system first checks whether there is a status entry corresponding to the security descriptor in the descriptor mapping table. If the first descriptor is not found in the mapping table, the system should immediately return an error code (such as EBADF) indicating that the descriptor cannot be used for the operation, which is usually because the descriptor has been closed or has never been allocated. If the first descriptor does exist in the mapping table, the system needs to obtain a mutex lock on the status entry, which is part of setting the data space to the fourth lock state to ensure that the closing operation is thread-safe. After the data space is locked, the system checks the close indicator bit in the status entry to confirm whether the first descriptor has been marked closed. If the value of the close indicator bit is a first preset value (such as 1 for closed), the system returns an error (such as EBADF) indicating that the first descriptor cannot be used because it has been closed. This is the purpose of the second prompt message.

[0143] Through the above-mentioned implementation methods of the present application, the security and reliability of file descriptor closing operations in a multi-threaded environment are ensured. Through strict locking and status verification strategies, the risks of file descriptor status confusion and data corruption caused by concurrent operations are avoided, providing a robust file access management solution for critical systems and high-concurrency services.

[0144] Example 3:

[0145] Figure 5 is a schematic diagram of an optional secure writing process according to an embodiment of the present application; Figure 5 As shown, if the fifth thread 502 wishes to write data to a storage device such as a disk, the fifth thread 502 may execute step S502 to send a third instruction to the security management layer 304. Upon receiving the third instruction, the security management layer 304 may execute step S504 to increment the reference count and execute step S506 to write the data to the interface provided by the kernel layer 306. Thereafter, the security management layer 304 may execute step S508 to decrement the reference count and finally execute step S510 to return a result to the fifth thread.

[0146] Specifically, during the secure read process, if any thread in the application layer (referred to as "thread A") needs to read data from disk into a buffer, it calls the encapsulated secure read interface (safe_read) instead of a direct system call. Thread A must provide a security descriptor (safe_fd) as a parameter, indicating the file resource it wishes to read.

[0147] Upon receiving a safe read request, the security management layer first attempts to acquire the global mapping table read lock to access and check the status entry. This is to verify the validity of safe_fd: that is, to check whether the descriptor is mapped to a real file descriptor (real_fd) and that the file is not closed. Once the read lock is acquired, the security management layer checks the status entry corresponding to safe_fd. If the status entry exists and indicates that the file is not closed, the security management layer checks the reference count to confirm that no other thread is attempting to close the file. If all is well, the security management layer increments the reference count and then releases the read lock.

[0148] The security management layer then uses real_fd to call the kernel's read interface. The kernel reads the data from disk and places it into the buffer specified by thread A. Upon successful read, the security management layer again acquires the mutex lock on the status entry and atomically decrements the reference count. If the reference count reaches zero and the file is marked closed, the security management layer notifies the threads waiting to close that they can proceed with the actual close operation. Finally, the security management layer reports the read result to thread A and clears any temporary state associated with this read, such as the incremented reference count.

[0149] The safe write process follows a similar initialization step to the safe read process. When thread B wishes to write data to disk, it calls the safe write interface (safe_write), providing safe_fd and the data buffer to be written. Upon receiving the write request, the security management layer first locks the global mapping table and then searches the status entry corresponding to safe_fd to verify that the file is open and not closed. It also checks the reference count to ensure that no close operation is in progress. If the status verification succeeds, the security management layer updates the reference count and then unlocks the mapping table. This ensures that the file descriptor is not accidentally closed during the write operation.

[0150] Using real_fd, the operating system kernel's write interface is called to write data from thread B's buffer to the specified file location on disk. After the write is complete, the security management layer updates the reference count and checks whether the file has been marked as closed. This check is crucial for preventing writes to closed files, thus avoiding data anomalies and corruption. If the reference count reaches zero and the file has been closed, the security management layer notifies threads waiting for the file to be closed via a condition variable, allowing them to perform the actual resource release and cleanup operations. The security management layer returns the result of the write operation to thread B, confirming that the data was successfully written to disk, or reports the reason for the write failure, such as insufficient disk space or permission issues.

[0151] By locking the global mapping table before and after read or write operations, the atomicity and exclusivity of file descriptor operations are ensured, preventing data contention and conflicts between multiple threads. The introduction and update of reference counts, combined with the checking of the close flag in the status entry, ensure the availability and consistency of file descriptors during read and write operations, avoiding the problem of using closed descriptors. The security management layer can perform additional error checks before and after read and write operations. If an anomaly is detected (such as illegal descriptor access, insufficient permissions, etc.), an error code can be immediately returned to the application thread, avoiding potential data corruption and system failures. The dynamic anomaly detection engine and status tracking mechanism can more accurately monitor and manage file descriptor resources, promptly clear unused descriptors, and avoid resource leaks and invalid occupation.

[0152] The secure read / write process ensures the security, consistency, and efficiency of file descriptor operations in multi-threaded environments through multi-level checks, inter-thread state synchronization, and conditional wait mechanisms. This process not only strengthens the management of file resources but also improves the stability and performance of server applications, especially in scenarios with high concurrency and high data integrity requirements.

[0153] The entry->cond condition variable is used to wait for the thread to wake up when the reference count reaches zero and the descriptor is marked as closed. This avoids deadlocks or long waits that can occur when trying to close the descriptor.

[0154] It should be noted that in a multi-threaded environment, the use and management of file descriptors becomes complex and can easily lead to a series of exceptions, such as use of closed descriptors, illegal access, and state inconsistency. To capture and handle these exceptions in real-time operations, a dynamic anomaly detection engine is introduced. As part of the security management layer, it uses a dual mechanism of state machine verification and operation interception to monitor abnormal use of file descriptors.

[0155] In an optional implementation, the use of closed descriptors can be detected. The anomaly detection engine checks the closed flag in the status entry to determine whether the descriptor is marked as closed. If the descriptor is detected to be closed, the engine immediately returns the error code EBADF, blocking the illegal access and recording the abnormal attempt for subsequent operation and maintenance audits.

[0156] In an optional implementation, illegal descriptor access can be detected. When a security descriptor does not exist in the global mapping table, the engine will determine that the access is illegal. For access to an illegal security descriptor, the engine will also return the EBADF error code and log the exception to prevent illegal operations on unknown or released resources.

[0157] In an optional implementation, state inconsistencies can be detected by calling fcntl F_GETFD to check whether the actual descriptor state is consistent with the state recorded in the state manager. If a state inconsistency is found, such as when the descriptor has been closed in the kernel but not marked in the state entry, the engine marks the state entry as "zombie" and triggers resource recycling to prevent system resource leaks and potential instability.

[0158] The core of the anomaly detection engine lies in real-time inspection and verification of the descriptor status, ensuring pre-verification before each file operation and post-audit after the operation. The following is an overview of the implementation process:

[0159] Before each security descriptor operation, the engine accesses the state manager to obtain the descriptor's current state and perform a validity check. At key operation points (such as descriptor closing and reuse), an atomic snapshot of the descriptor's state is obtained to ensure state consistency and integrity. After the operation is completed, the descriptor state is rechecked to confirm that no abnormal changes have occurred, such as accidental closing or illegal reuse.

[0160] The anomaly detection engine instantly blocks unauthorized access, ensuring system consistency and security. Each time an anomaly is detected, the engine records detailed operational context, including the operation type, process / thread information, and timestamps, to facilitate subsequent problem tracking and analysis. The engine also generates an anomaly diagnostic report, helping operations personnel quickly identify the cause of the problem and implement remedial measures.

[0161] It's important to note that deadlock is a common problem in multithreaded applications. It typically occurs when multiple threads wait for each other's locks to be released, causing the entire system to stall. Using a condition variable with a timeout to wait effectively avoids this problem, ensuring smooth operation and system stability.

[0162] Use the clock_gettime function to get the current time and store it in the struct timespec ts, which is the basis for setting the timeout wait. Increase the number of seconds ts.tv_sec in the struct timespec by TIMEOUT_SEC seconds, which defines the maximum time for the conditional wait.

[0163] A thread uses the pthread_cond_timedwait function to wait on a condition variable, providing the address of a mutex lock. This ensures that the lock cannot be acquired by other threads during the wait, thus avoiding double locking. This function waits until the condition is satisfied (in this case, the reference count reaches zero) or the timeout period expires. If pthread_cond_timedwait returns the ETIMEDOUT error code, this means that the wait timed out and the condition was not satisfied, indicating a possible deadlock or exception.

[0164] At this point, the system needs to execute emergency handling procedures, including: calling the handle_deadlock function, which analyzes the lock acquisition status between the current threads and attempts to identify the root cause of the deadlock. Calling the emergency_close function to immediately close the actual file descriptor real_fd associated with entry to prevent long-term resource occupation and possible data corruption. Calling the generate_diagnostic function to record the current status and specific information that caused the timeout, including but not limited to the thread ID, descriptor ID, and reference count, to facilitate subsequent operation and maintenance personnel to locate and resolve the problem.

[0165] In this code snippet, entry refers to the state entry associated with a particular security descriptor. When a thread attempts to perform a safe close operation, it checks if the reference count in entry is zero. If there are no other threads referencing the descriptor, the thread can safely close it. However, if the reference count is not zero, the thread waits for a specific time period, TIMEOUT_SEC seconds, to allow other threads to complete their operations. If the waiting time exceeds the set TIMEOUT_SEC seconds, i.e., result == ETIMEDOUT, it is considered that a deadlock or abnormal situation may occur, and the system calls the deadlock handling function handle_deadlock, performs emergency_close for forced closing, and generates a diagnostic report through generate_diagnostic. This ensures that even in extreme cases, the system can respond in a timely manner and take appropriate recovery measures.

[0166] Figure 6 is a schematic diagram of an optional multi-threaded file management according to an embodiment of the present application; as shown, the whole can be divided into an application layer 602, a security management layer 604 and a kernel layer 606, wherein the application layer 602 and the kernel layer 606 exist in the existing file access process, and the security management layer 604 is unique in the scheme of the present application, and the above multi-threaded file management method is mostly executed in this layer. Figure 6

[0167] Specifically, the application layer 602 and the kernel layer 606 are the core part of the operating system, responsible for handling low-level management of hardware resources, including scheduling threads, memory management, device drivers, and providing system call interfaces. At this level, consistency with the original design of the system is maintained, and no code or logic at the kernel level is modified to ensure compatibility and stability, while avoiding the introduction of new kernel-level bugs or security risks.

[0168] ​The security management layer 604 creates an intermediate layer to map security descriptors requested by the application layer to actual descriptors at the operating system level. This provides an additional layer of protection and management to prevent errors in descriptor-related operations. To ensure the safe closing and reuse of file descriptors in a multi-threaded environment, the security management layer maintains a reference count for each descriptor. This allows the descriptor to be checked before it is actually closed to determine whether it is currently being used by other threads, preventing data corruption and undefined behavior. Before the application layer attempts file operations, the security management layer intercepts these calls and verifies the state of the descriptor. It ensures that operations such as reading and writing can only be performed when the descriptor is in the appropriate state (for example, not closed and not reused). To implement descriptor mapping and state tracking, the security management layer maintains a global mapping table in which each security descriptor is associated with a state entry. The state entry contains the descriptor's actual value, reference count, close flag, and other relevant metadata such as the creator PID, TID, and creation timestamp.

[0169] For the security management layer, it can be a zero-intrusion integration system that allows the security of file descriptors to be enhanced without modifying the application source code.

[0170] In an optional implementation, LD_PRELOAD transparent replacement can be used, a Linux-specific feature that allows specific libraries to be dynamically loaded into memory during program execution. By setting LD_PRELOAD=. / libfdguard.so as an environment variable, when a program is launched (e.g., . / my_server), system calls such as open, read, write, and close that would normally call the kernel layer are automatically replaced with corresponding functions in the security management layer, achieving seamless integration of enhanced security features.

[0171] In an optional implementation, the APIs provided by the security management layer, such as safe_open, safe_read, safe_write, and safe_close, strictly adhere to the POSIX standard for parameter lists and function descriptions. This means that applications can call these APIs directly, just like calling standard system calls, without any additional learning or modification. Whether preloading via LD_PRELOAD or directly calling the security management layer's APIs, there's no need to modify the application's source code; only the method for loading the security library needs to be configured. This greatly facilitates applications in enhancing the security of their file descriptor operations without disrupting existing functionality.

[0172] Example 4:

[0173] Figure 7 is a schematic diagram of another optional multi-threaded file management according to an embodiment of the present application;Figure 7 As shown, the seventh thread 702 can execute step S702 to send a fourth instruction, which can be an instruction to close the corresponding file, and the specific safe closing process is described above. The fourth instruction can be safe_close (10001), and 10001 is the first descriptor. After receiving the fourth instruction, the security management layer 304 can access the descriptor mapping table, and in the case of 10001, execute step S704 to remove the mapping relationship of the first descriptor (10001). In the case where the eighth thread 704 also closes the file subsequently, execute step S706 to send a fifth instruction, which can be safe_close (10001). The security management layer 304 executes step S708 to access the descriptor mapping table to find the mapping relationship of the first descriptor. Therefore, the mapping relationship has been removed in S704, and thus the first descriptor (10001) cannot be found, and step S710 is executed to return a result. The eighth thread 704 can directly execute the closing operation close (10001) to return an error indication.

[0174] Embodiment 5:

[0175] However, in the case of a descriptor reuse conflict, the method of the present application can be used to avoid it. Specifically, for example, the first descriptor 10001 and the second descriptor 5 have a mapping relationship, the second descriptor 5 indicates file A, and thread A can access file A through the first descriptor 10001. At this time, thread B can send a safe_close (10001) instruction to close file A and remove the first descriptor 10001, and at the same time, the second descriptor 5 is also removed from the corresponding relationship with file A.

[0176] Subsequently, thread C opens file B, which can establish a corresponding relationship with the second descriptor 5 and obtain the first descriptor 10002, and establish a mapping relationship between the first descriptor 10002 and the second descriptor 5. In the case where thread A does not perceive the closing of file A and still wants to use file A, thread A accesses the interface of the kernel through the first descriptor 10001, but the security management layer does not find the first descriptor 10001, and then returns an error message to thread A.

[0177] In an optional embodiment, the management of the original safe descriptor (safe_fd) life cycle can be improved, and an intelligent diagnosis system can be introduced to automatically identify and handle potential system abnormalities and security vulnerabilities.

[0178] Leveraging machine learning algorithms to analyze historical operation patterns and file descriptor usage frequency, the system predicts future operational trends and provides early warning of potential descriptor conflicts, leaks, or improper usage. Building on the dynamic anomaly detection engine, the system further analyzes the operational context, including file type, the frequency and pattern of operation requests, and thread attributes related to the operation (e.g., priority, suspended state). When an anomaly is detected, the system not only logs the detected anomaly but also attempts to automatically restore the system state, such as restarting affected services or reallocating resources.

[0179] The global mapping table is scanned regularly to identify unused security descriptors and their associated resources (such as unclosed file descriptors), automatically triggering the safe shutdown protocol to prevent resource leaks. Security descriptors can be transferred between threads by creating a shared descriptor mapping data structure and introducing a descriptor ownership exchange mechanism to ensure data security and consistency when transferring file descriptors between threads. The security descriptor status entry is expanded to include fine-grained permission control information, such as read, write, and execute permissions, as well as thread-specific access rights. Illegal or unauthorized file descriptor operations are filtered out through a permission check mechanism.

[0180] In an optional implementation, metadata such as usage frequency, operation type, and operation time for each security descriptor is continuously monitored and stored in a dedicated historical data store. Using supervised learning methods, a model is trained to predict descriptor usage patterns and potential conflict risks. When the model predicts high-risk operational trends, an early warning signal is sent to the application layer, recommending preemptive action, such as delaying certain operations or prioritizing critical tasks.

[0181] When a suspected abnormal operation is detected, the anomaly detection engine not only examines the status entry but also conducts in-depth analysis of the operation context to assess the severity and impact of the anomaly. Based on the anomaly type and context, it intelligently determines whether and how to perform recovery actions, such as automatically rolling back to the last stable state, restarting the service, or reallocating resources.

[0182] Adding read, write, execute, and thread-specific permission fields to the status entry. Before each descriptor operation, in addition to checking the closed state and reference count, the operator's permissions are also verified to ensure they are sufficient, further enhancing system security.

[0183] Consider a highly concurrent database server application that needs to share file descriptors across multiple service threads to access database files. When a thread needs to transfer file descriptor permissions to another thread, not only can resource migration be performed safely, but access permissions to the file descriptors are also properly managed and controlled before and after the migration. Simultaneously, the system automatically detects and warns of unusual descriptor usage patterns, such as continuous, high-frequency reads and writes, and promptly adjusts resource allocation strategies to avoid potential system crashes or service interruptions. When resource leaks are detected, the intelligent diagnostic system automatically reclaims the relevant resources, preventing memory leaks and excessive file system resource usage, maintaining long-term stable system operation.

[0184] Through the description of the above implementation methods, those skilled in the art can clearly understand that the method according to the above embodiment can be implemented by means of software plus the necessary general hardware platform, and of course it can also be implemented by hardware, but in many cases the former is a better implementation method.

[0185] The embodiment of the present application also provides a multi-threaded file management device, Figure 8 This is a structural block diagram of an optional multi-threaded file management device according to an embodiment of the present application. Figure 8 As shown, the device includes:

[0186] A first receiving module 802 is configured to receive a first instruction sent by a first thread, wherein the first instruction is used to instruct to close a target file, and the first instruction includes a first descriptor;

[0187] A search module 804 is configured to access a descriptor mapping table to search for a second descriptor corresponding to the first descriptor, wherein the second descriptor is used to indicate a target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor;

[0188] The mapping table adjustment module 806 is configured to delete the mapping relationship when the first descriptor exists in the descriptor mapping table, and close the target file based on the second descriptor.

[0189] Optionally, the mapping table adjustment module 806 is further used to: read the data space corresponding to the first descriptor, wherein the data space is used to indicate the status of the first descriptor; determine the number of references included in the data space, wherein the number of references is used to indicate the number of threads currently accessing the target file; and when the number of references is a preset number, close the target file based on the second descriptor.

[0190] Optionally, the mapping table adjustment module 806 is further used to: set the data space corresponding to the first descriptor to a first locked state, wherein the first locked state is used to indicate that the data space is prohibited from being accessed by at least one second thread, and the second thread is not the first thread; set the close indication bit included in the data space to a first preset value, wherein the first preset value is used to indicate that the first descriptor is in a closed state; set the data space corresponding to the first descriptor to a first unlocked state, wherein the first unlocked state is used to indicate that the data space can be accessed by the first thread and at least one second thread.

[0191] Optionally, the search module 804 is further configured to: set the descriptor mapping table to a second locking state, wherein the second locking state is used to indicate that the descriptor mapping table is prohibited from being accessed by at least one second thread;

[0192] Optionally, the mapping table adjustment module 806 is further configured to set the descriptor mapping table to a second unlocked state, wherein the second unlocked state is used to indicate that the descriptor mapping table can be accessed by the first thread and at least one second thread.

[0193] Optionally, the above-mentioned first receiving module 802 is also used to: receive a second instruction sent by a third thread, wherein the second instruction is used to instruct to open a target file, wherein the third thread and the first thread belong to the same process space; generate a first descriptor and a second descriptor; establish a mapping relationship between the first descriptor and the second descriptor; access the descriptor mapping table, and store the mapping relationship in the descriptor mapping table.

[0194] Optionally, the above-mentioned search module 804 is also used to: set the descriptor mapping table to a third locked state, wherein the third locked state is used to indicate that the descriptor mapping table is prohibited from being accessed by at least one fourth thread, and the fourth thread is not a third thread; set the descriptor mapping table to a third unlocked state, wherein the third unlocked state is used to indicate that the descriptor mapping table can be accessed by the third thread and at least one fourth thread.

[0195] Optionally, the above-mentioned first receiving module 802 is also used to: receive a third instruction sent by the fifth thread, wherein the third instruction is used to instruct to read data from the target file or write data to the target file, the third instruction includes a first descriptor, and the fifth thread and the first thread belong to the same process space; access the descriptor mapping table to find the second descriptor corresponding to the first descriptor; when the first descriptor exists in the descriptor mapping table, read the data space corresponding to the first descriptor, and increase the number of references included in the data space by one; perform the read or write operation indicated by the third instruction on the target file; and reduce the number of references included in the data space by one.

[0196] Optionally, the above-mentioned first receiving module 802 is also used to: set the data space corresponding to the first descriptor to a fourth locked state, wherein the fourth locked state is used to indicate that the data space is prohibited from being accessed by at least one sixth thread, and the sixth thread is not the fifth thread; increase the number of references included in the data space by one; set the data space corresponding to the first descriptor to a fourth unlocked state, wherein the fourth unlocked state is used to indicate that the data space can be accessed by the fifth thread and at least one sixth thread; set the data space corresponding to the first descriptor to a fourth locked state; reduce the number of references included in the data space by one; and set the data space corresponding to the first descriptor to a fourth unlocked state.

[0197] Optionally, the above-mentioned search module 804 is also used to: when the first descriptor does not exist in the descriptor mapping table, return a first prompt message, wherein the first prompt message is used to indicate that the first descriptor is not available; determine the value of the close indication bit included in the data space; when the value of the close indication bit is a first preset value, return a second prompt message, wherein the second prompt message is used to indicate that the first descriptor is not available.

[0198] For the description of the features in the embodiment corresponding to the multi-threaded file management device, please refer to the relevant description of the embodiment corresponding to the multi-threaded file management method, which will not be repeated here.

[0199] An embodiment of the present application further provides an electronic device, comprising a memory and a processor, wherein the memory stores a computer program, and the processor is configured to run the computer program to execute the steps of any of the above-mentioned multi-threaded file management method embodiments.

[0200] An embodiment of the present application further provides a computer-readable storage medium, in which a computer program is stored, wherein the computer program is configured to execute the steps of any of the above-mentioned multi-threaded file management method embodiments when running.

[0201] In an exemplary embodiment, the computer-readable storage medium may include, but is not limited to, various media that can store computer programs, such as a USB flash drive, a read-only memory (ROM), a random access memory (RAM), a mobile hard disk, a magnetic disk, or an optical disk.

[0202] An embodiment of the present application further provides a computer program product, which includes a computer program. When the computer program is executed by a processor, the steps of any of the above-mentioned multi-threaded file management method embodiments are implemented.

[0203] An embodiment of the present application also provides another computer program product, including a non-volatile computer-readable storage medium, which stores a computer program. When the computer program is executed by a processor, it implements the steps of any of the above-mentioned multi-threaded file management method embodiments.

[0204] Professionals may further appreciate that the units and algorithm steps of each example described in conjunction with the embodiments disclosed herein can be implemented in electronic hardware, computer software, or a combination of the two. In order to clearly illustrate the interchangeability of hardware and software, the above description has generally described the components and steps of each example according to their functions. Whether these functions are performed in hardware or software depends on the specific application and design constraints of the technical solution. Professionals and technicians may use different methods to implement the described functions for each specific application, but such implementation should not be considered beyond the scope of this application.

[0205] The above is a detailed introduction to a multi-threaded file management method and device, storage medium, and electronic device provided by the present application. Specific examples are used herein to illustrate the principles and implementation methods of the present application. The description of the above embodiments is only intended to help understand the method and core ideas of the present application. It should be pointed out that, for those skilled in the art, without departing from the principles of the present application, several improvements and modifications can be made to the present application, and these improvements and modifications also fall within the scope of protection of the claims of the present application.

Claims

1. A multi-threaded file management method, characterized in that: include: receiving a first instruction sent by a first thread, wherein the first instruction is used to instruct closing a target file, and the first instruction includes a first descriptor; Accessing a descriptor mapping table to search for a second descriptor corresponding to the first descriptor, wherein the second descriptor is used to indicate the target file, and the descriptor mapping table is used to store a mapping relationship between the first descriptor and the second descriptor; In a case where the first descriptor exists in the descriptor mapping table, the mapping relationship is deleted, and the target file is closed based on the second descriptor.

2. The method according to claim 1, characterized in that Closing the target file based on the second descriptor includes: Reading a data space corresponding to the first descriptor, wherein the data space is used to indicate a state of the first descriptor; Determining a reference count included in the data space, wherein the reference count is used to indicate the number of threads currently accessing the target file; When the number of references is a preset number, the target file is closed based on the second descriptor.

3. The method according to claim 2, characterized in that Before determining the number of references included in the data space, the method further includes: Setting the data space corresponding to the first descriptor to a first locking state, wherein the first locking state is used to indicate that the data space is prohibited from being accessed by at least one second thread, where the second thread is not the first thread; Setting a close indication bit included in the data space to a first preset value, wherein the first preset value is used to indicate that the first descriptor is in a closed state; After closing the target file based on the second descriptor, the method further comprises: The data space corresponding to the first descriptor is set to a first unlocked state, wherein the first unlocked state is used to indicate that the data space is accessible to the first thread and at least one of the second threads.

4. The method according to claim 3, characterized in that Before the access descriptor mapping table, it includes: Setting the descriptor mapping table to a second locking state, wherein the second locking state is used to indicate that the descriptor mapping table is prohibited from being accessed by at least one second thread; After deleting the mapping relationship, the method further includes: The descriptor mapping table is set to a second unlocked state, wherein the second unlocked state is used to indicate that the descriptor mapping table is accessible to the first thread and at least one of the second threads.

5. The method according to any one of claims 1 to 4, characterized in that Before receiving the first instruction sent by the first thread, the method includes: receiving a second instruction sent by a third thread, wherein the second instruction is used to instruct to open the target file, wherein the third thread and the first thread belong to the same process space; generating the first descriptor and the second descriptor; Establishing the mapping relationship between the first descriptor and the second descriptor; The descriptor mapping table is accessed, and the mapping relationship is stored in the descriptor mapping table.

6. The method according to claim 5, characterized in that Before accessing the descriptor mapping table, the method further includes: Setting the descriptor mapping table to a third locking state, wherein the third locking state is used to indicate that the descriptor mapping table is prohibited from being accessed by at least one fourth thread, where the fourth thread is not the third thread; After storing the mapping relationship in the descriptor mapping table, the method further includes: The descriptor mapping table is set to a third unlocked state, wherein the third unlocked state is used to indicate that the descriptor mapping table is accessible by the third thread and at least one fourth thread.

7. The method according to claim 5, characterized in that After storing the mapping relationship in the descriptor mapping table, the method further includes: receiving a third instruction sent by a fifth thread, wherein the third instruction is used to instruct reading data from the target file or writing data to the target file, the third instruction includes the first descriptor, and the fifth thread and the first thread belong to the same process space; Accessing the descriptor mapping table to search for the second descriptor corresponding to the first descriptor; If the first descriptor exists in the descriptor mapping table, read the data space corresponding to the first descriptor, and increase the number of references included in the data space by one; Executing a read or write operation indicated by the third instruction on the target file; The number of references included in the data space is reduced by one.

8. The method according to claim 7, characterized in that Increasing the number of references included in the data space by one includes: Setting the data space corresponding to the first descriptor to a fourth locking state, wherein the fourth locking state is used to indicate that the data space is prohibited from being accessed by at least one sixth thread, where the sixth thread is not the fifth thread; Increasing the number of references included in the data space by one; Setting the data space corresponding to the first descriptor to a fourth unlock state, wherein the fourth unlock state is used to indicate that the data space is accessible to the fifth thread and at least one of the sixth threads; The step of reducing the number of references in the data space by one comprises: Setting the data space corresponding to the first descriptor to the fourth locking state; Decrease the number of references included in the data space by one; The data space corresponding to the first descriptor is set to a fourth unlocked state.

9. The method according to claim 8, characterized in that After accessing the descriptor mapping table and searching for the second descriptor corresponding to the first descriptor, the method further includes: If the first descriptor does not exist in the descriptor mapping table, returning first prompt information, wherein the first prompt information is used to indicate that the first descriptor is unavailable; Setting the data space corresponding to the first descriptor to a fourth locked state includes: determining a value of a close indication bit included in the data space; When the value of the close indication bit is a first preset value, second prompt information is returned, wherein the second prompt information is used to indicate that the first descriptor is unavailable.

10. An electronic device, characterized in that: include: memory for storing computer programs; A processor, configured to implement the steps of the multi-threaded file management method according to any one of claims 1 to 9 when executing the computer program.

Citation Information

Patent Citations

  • Process context mandatory access control method

    CN104133726A

  • Data real-time storage system and method based on Linux

    CN111338853A

  • Metadata multi-concurrency control method and system and related components

    CN116089389A

  • File indexing for virtual machine backups in a data storage management system

    US20200233846A1

  • XML presentation of general-purpose data sources

    US6901403B1