f2fs学习三: 文件系统初始化
一. F2FS文件系统初始化
static int __init init_f2fs_fs(void)
{int err;/* PAGE_SIZE和F2FS_BLKSIZE需要相等, 大小为4096*/if (PAGE_SIZE != F2FS_BLKSIZE) {printk("F2FS not supported on PAGE_SIZE(%lu) != %d\n",PAGE_SIZE, F2FS_BLKSIZE);return -EINVAL;}f2fs_build_trace_ios();/* 初始化f2fs_inode_cache */err = init_inodecache();if (err)goto fail;err = f2fs_create_node_manager_caches();if (err)goto free_inodecache;err = f2fs_create_segment_manager_caches();if (err)goto free_node_manager_caches;err = f2fs_create_checkpoint_caches();if (err)goto free_segment_manager_caches;err = f2fs_create_extent_cache();if (err)goto free_checkpoint_caches;err = f2fs_init_sysfs();if (err)goto free_extent_cache;err = register_shrinker(&f2fs_shrinker_info);if (err)goto free_sysfs;err = register_filesystem(&f2fs_fs_type);if (err)goto free_shrinker;f2fs_create_root_stats();err = f2fs_init_post_read_processing();if (err)goto free_root_stats;return 0;free_root_stats:f2fs_destroy_root_stats();unregister_filesystem(&f2fs_fs_type);
free_shrinker:unregister_shrinker(&f2fs_shrinker_info);
free_sysfs:f2fs_exit_sysfs();
free_extent_cache:f2fs_destroy_extent_cache();
free_checkpoint_caches:f2fs_destroy_checkpoint_caches();
free_segment_manager_caches:f2fs_destroy_segment_manager_caches();
free_node_manager_caches:f2fs_destroy_node_manager_caches();
free_inodecache:destroy_inodecache();
fail:return err;
}
初始化f2fs_inode_cache, 申请f2fs_inode_info内存空间,f2fs_inode_info是描述f2fs inode 信息的结构体
static int __init init_inodecache(void)
{f2fs_inode_cachep = kmem_cache_create("f2fs_inode_cache",sizeof(struct f2fs_inode_info), 0,SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, NULL);if (!f2fs_inode_cachep)return -ENOMEM;return 0;
}struct f2fs_inode_info {struct inode vfs_inode; /* serve a vfs inode */unsigned long i_flags; /* keep an inode flags for ioctl */unsigned char i_advise; /* use to give file attribute hints */unsigned char i_dir_level; /* use for dentry level for large dir */unsigned int i_current_depth; /* only for directory depth *//* for gc failure statistic */unsigned int i_gc_failures[MAX_GC_FAILURE];unsigned int i_pino; /* parent inode number */umode_t i_acl_mode; /* keep file acl mode temporarily *//* Use below internally in f2fs*/unsigned long flags; /* use to pass per-file flags */struct rw_semaphore i_sem; /* protect fi info */atomic_t dirty_pages; /* # of dirty pages */f2fs_hash_t chash; /* hash value of given file name */unsigned int clevel; /* maximum level of given file name */struct task_struct *task; /* lookup and create consistency */struct task_struct *cp_task; /* separate cp/wb IO stats*/nid_t i_xattr_nid; /* node id that contains xattrs */loff_t last_disk_size; /* lastly written file size */#ifdef CONFIG_QUOTAstruct dquot *i_dquot[MAXQUOTAS];/* quota space reservation, managed internally by quota code */qsize_t i_reserved_quota;
#endifstruct list_head dirty_list; /* dirty list for dirs and files */struct list_head gdirty_list; /* linked in global dirty list */struct list_head inmem_ilist; /* list for inmem inodes */struct list_head inmem_pages; /* inmemory pages managed by f2fs */struct task_struct *inmem_task; /* store inmemory task */struct mutex inmem_lock; /* lock for inmemory pages */struct extent_tree *extent_tree; /* cached extent_tree entry *//* avoid racing between foreground op and gc */struct rw_semaphore i_gc_rwsem[2];struct rw_semaphore i_mmap_sem;struct rw_semaphore i_xattr_sem; /* avoid racing between reading and changing EAs */int i_extra_isize; /* size of extra space located in i_addr */kprojid_t i_projid; /* id for project quota */int i_inline_xattr_size; /* inline xattr size */struct timespec64 i_crtime; /* inode creation time */struct timespec64 i_disk_time[4];/* inode disk times */
};
申请f2fs node 管理相关的slab 内存空间,描述 node管理信息相关的结构体是 nat_entry, free_nid, nat_entry_set, fsync_node_entry.
int __init f2fs_create_node_manager_caches(void)
{nat_entry_slab = f2fs_kmem_cache_create("nat_entry",sizeof(struct nat_entry));if (!nat_entry_slab)goto fail;free_nid_slab = f2fs_kmem_cache_create("free_nid",sizeof(struct free_nid));if (!free_nid_slab)goto destroy_nat_entry;nat_entry_set_slab = f2fs_kmem_cache_create("nat_entry_set",sizeof(struct nat_entry_set));if (!nat_entry_set_slab)goto destroy_free_nid;fsync_node_entry_slab = f2fs_kmem_cache_create("fsync_node_entry",sizeof(struct fsync_node_entry));if (!fsync_node_entry_slab)goto destroy_nat_entry_set;return 0;destroy_nat_entry_set:kmem_cache_destroy(nat_entry_set_slab);
destroy_free_nid:kmem_cache_destroy(free_nid_slab);
destroy_nat_entry:kmem_cache_destroy(nat_entry_slab);
fail:return -ENOMEM;
}struct nat_entry {struct list_head list; /* for clean or dirty nat list */struct node_info ni; /* in-memory node information */
};/** For node information*/
struct node_info {nid_t nid; /* node id */nid_t ino; /* inode number of the node's owner */block_t blk_addr; /* block address of the node */unsigned char version; /* version of the node */unsigned char flag; /* for node information bits */
};struct free_nid {struct list_head list; /* for free node id list */nid_t nid; /* node id */int state; /* in use or not: FREE_NID or PREALLOC_NID */
};struct nat_entry_set {struct list_head set_list; /* link with other nat sets */struct list_head entry_list; /* link with dirty nat entries */nid_t set; /* set number*/unsigned int entry_cnt; /* the # of nat entries in set */
};struct fsync_node_entry {struct list_head list; /* list head */struct page *page; /* warm node page pointer */unsigned int seq_id; /* sequence id */
};
申请f2fs segment管理相关的slab 内存空间,描述segment管理信息相关的结构体是 discard_entry, discard_cmd, sit_entry_set, inmem_pages.
int __init f2fs_create_segment_manager_caches(void)
{discard_entry_slab = f2fs_kmem_cache_create("discard_entry",sizeof(struct discard_entry));if (!discard_entry_slab)goto fail;discard_cmd_slab = f2fs_kmem_cache_create("discard_cmd",sizeof(struct discard_cmd));if (!discard_cmd_slab)goto destroy_discard_entry;sit_entry_set_slab = f2fs_kmem_cache_create("sit_entry_set",sizeof(struct sit_entry_set));if (!sit_entry_set_slab)goto destroy_discard_cmd;inmem_entry_slab = f2fs_kmem_cache_create("inmem_page_entry",sizeof(struct inmem_pages));if (!inmem_entry_slab)goto destroy_sit_entry_set;return 0;destroy_sit_entry_set:kmem_cache_destroy(sit_entry_set_slab);
destroy_discard_cmd:kmem_cache_destroy(discard_cmd_slab);
destroy_discard_entry:kmem_cache_destroy(discard_entry_slab);
fail:return -ENOMEM;
}/* for the bitmap indicate blocks to be discarded */
struct discard_entry {struct list_head list; /* list head */block_t start_blkaddr; /* start blockaddr of current segment */unsigned char discard_map[SIT_VBLOCK_MAP_SIZE]; /* segment discard bitmap */
};struct discard_cmd {struct rb_node rb_node; /* rb node located in rb-tree */union {struct {block_t lstart; /* logical start address */block_t len; /* length */block_t start; /* actual start address in dev */};struct discard_info di; /* discard info */};struct list_head list; /* command list */struct completion wait; /* compleation */struct block_device *bdev; /* bdev */unsigned short ref; /* reference count */unsigned char state; /* state */unsigned char queued; /* queued discard */int error; /* bio error */spinlock_t lock; /* for state/bio_ref updating */unsigned short bio_ref; /* bio reference count */
};struct sit_entry_set {struct list_head set_list; /* link with all sit sets */unsigned int start_segno; /* start segno of sits in set */unsigned int entry_cnt; /* the # of sit entries in set */
};struct sit_entry_set {struct list_head set_list; /* link with all sit sets */unsigned int start_segno; /* start segno of sits in set */unsigned int entry_cnt; /* the # of sit entries in set */
};
申请f2fs checkpoint管理相关的slab 内存空间,描述checkpoint管理信息相关的结构体是.inode_entry
int __init f2fs_create_checkpoint_caches(void)
{ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry",sizeof(struct ino_entry));if (!ino_entry_slab)return -ENOMEM;f2fs_inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",sizeof(struct inode_entry));if (!f2fs_inode_entry_slab) {kmem_cache_destroy(ino_entry_slab);return -ENOMEM;}return 0;
}/* for the list of inodes to be GCed */
struct inode_entry {struct list_head list; /* list head */struct inode *inode; /* vfs inode pointer */
};
创建f2fs extent cache内存空间
int __init f2fs_create_extent_cache(void)
{extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree",sizeof(struct extent_tree));if (!extent_tree_slab)return -ENOMEM;extent_node_slab = f2fs_kmem_cache_create("f2fs_extent_node",sizeof(struct extent_node));if (!extent_node_slab) {kmem_cache_destroy(extent_tree_slab);return -ENOMEM;}return 0;
}struct extent_info {unsigned int fofs; /* start offset in a file */unsigned int len; /* length of the extent */u32 blk; /* start block address of the extent */
};struct extent_node {struct rb_node rb_node; /* rb node located in rb-tree */struct extent_info ei; /* extent info */struct list_head list; /* node in global extent list of sbi */struct extent_tree *et; /* extent tree pointer */
};struct extent_tree {nid_t ino; /* inode number */struct rb_root_cached root; /* root of extent info rb-tree */struct extent_node *cached_en; /* recently accessed extent node */struct extent_info largest; /* largested extent info */struct list_head list; /* to be used by sbi->zombie_list */rwlock_t lock; /* protect extent info rb-tree */atomic_t node_cnt; /* # of extent node in rb-tree*/bool largest_updated; /* largest extent updated */
};
创建sys/fs/f2fs目录
int __init f2fs_init_sysfs(void)
{int ret;kobject_set_name(&f2fs_kset.kobj, "f2fs");f2fs_kset.kobj.parent = fs_kobj;ret = kset_register(&f2fs_kset);if (ret)return ret;ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,NULL, "features");if (ret)kset_unregister(&f2fs_kset);elsef2fs_proc_root = proc_mkdir("fs/f2fs", NULL);return ret;
}
注册f2fs_shrinker_info信息
int register_shrinker(struct shrinker *shrinker)
{int err = prealloc_shrinker(shrinker);if (err)return err;register_shrinker_prepared(shrinker);return 0;
}/* f2fs-wide shrinker description */
static struct shrinker f2fs_shrinker_info = {.scan_objects = f2fs_shrink_scan,.count_objects = f2fs_shrink_count,.seeks = DEFAULT_SEEKS,
};
注册f2fs文件系统
/*** register_filesystem - register a new filesystem* @fs: the file system structure** Adds the file system passed to the list of file systems the kernel* is aware of for mount and other syscalls. Returns 0 on success,* or a negative errno code on an error.** The &struct file_system_type that is passed is linked into the kernel * structures and must not be freed until the file system has been* unregistered.*/int register_filesystem(struct file_system_type * fs)
{int res = 0;struct file_system_type ** p;BUG_ON(strchr(fs->name, '.'));if (fs->next)return -EBUSY;write_lock(&file_systems_lock);p = find_filesystem(fs->name, strlen(fs->name));if (*p)res = -EBUSY;else*p = fs;write_unlock(&file_systems_lock);return res;
}static struct file_system_type f2fs_fs_type = {.owner = THIS_MODULE,.name = "f2fs",.mount = f2fs_mount,.kill_sb = kill_f2fs_super,.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("f2fs");
f2fs create root tats
void __init f2fs_create_root_stats(void)
{f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL);debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root, NULL,&stat_fops);
}/* DEFINE_SHOW_ATTRIBUTE是将 __name ## _open和__name ## _fops封装之后的宏,达到简化的效果,
我们只需要去实现 __name ## _show(这里是指的是stat_show函数),当用户读取status文件时,会直接调用__name ## _show函数(即调用stat_show函数)
DEFINE_SHOW_ATTRIBUTE(stat);#define DEFINE_SHOW_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct file *file) \
{ \return single_open(file, __name ## _show, inode->i_private); \
} \\
static const struct file_operations __name ## _fops = { \.owner = THIS_MODULE, \.open = __name ## _open, \.read = seq_read, \.llseek = seq_lseek, \.release = single_release, \
}static void *single_start(struct seq_file *p, loff_t *pos)
{return NULL + (*pos == 0);
}static void *single_next(struct seq_file *p, void *v, loff_t *pos)
{++*pos;return NULL;
}static void single_stop(struct seq_file *p, void *v)
{
}int single_open(struct file *file, int (*show)(struct seq_file *, void *),void *data)
{struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL_ACCOUNT);int res = -ENOMEM;if (op) {op->start = single_start;op->next = single_next;op->stop = single_stop;op->show = show;res = seq_open(file, op);if (!res)((struct seq_file *)file->private_data)->private = data;elsekfree(op);}return res;
}
EXPORT_SYMBOL(single_open);static int stat_show(struct seq_file *s, void *v)
{struct f2fs_stat_info *si;int i = 0;int j;mutex_lock(&f2fs_stat_mutex);list_for_each_entry(si, &f2fs_stat_list, stat_list) {update_general_status(si->sbi);seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n",si->sbi->sb->s_bdev, i++,f2fs_readonly(si->sbi->sb) ? "RO": "RW",is_set_ckpt_flags(si->sbi, CP_DISABLED_FLAG) ?"Disabled": (f2fs_cp_error(si->sbi) ? "Error": "Good"));seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",si->sit_area_segs, si->nat_area_segs);seq_printf(s, "[SSA: %d] [MAIN: %d",si->ssa_area_segs, si->main_area_segs);seq_printf(s, "(OverProv:%d Resv:%d)]\n\n",si->overp_segs, si->rsvd_segs);if (test_opt(si->sbi, DISCARD))seq_printf(s, "Utilization: %u%% (%u valid blocks, %u discard blocks)\n",si->utilization, si->valid_count, si->discard_blks);elseseq_printf(s, "Utilization: %u%% (%u valid blocks)\n",si->utilization, si->valid_count);seq_printf(s, " - Node: %u (Inode: %u, ",si->valid_node_count, si->valid_inode_count);seq_printf(s, "Other: %u)\n - Data: %u\n",si->valid_node_count - si->valid_inode_count,si->valid_count - si->valid_node_count);seq_printf(s, " - Inline_xattr Inode: %u\n",si->inline_xattr);seq_printf(s, " - Inline_data Inode: %u\n",si->inline_inode);seq_printf(s, " - Inline_dentry Inode: %u\n",si->inline_dir);seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n",si->orphans, si->append, si->update);seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",si->main_area_segs, si->main_area_sections,si->main_area_zones);seq_printf(s, " - COLD data: %d, %d, %d\n",si->curseg[CURSEG_COLD_DATA],si->cursec[CURSEG_COLD_DATA],si->curzone[CURSEG_COLD_DATA]);seq_printf(s, " - WARM data: %d, %d, %d\n",si->curseg[CURSEG_WARM_DATA],si->cursec[CURSEG_WARM_DATA],si->curzone[CURSEG_WARM_DATA]);seq_printf(s, " - HOT data: %d, %d, %d\n",si->curseg[CURSEG_HOT_DATA],si->cursec[CURSEG_HOT_DATA],si->curzone[CURSEG_HOT_DATA]);seq_printf(s, " - Dir dnode: %d, %d, %d\n",si->curseg[CURSEG_HOT_NODE],si->cursec[CURSEG_HOT_NODE],si->curzone[CURSEG_HOT_NODE]);seq_printf(s, " - File dnode: %d, %d, %d\n",si->curseg[CURSEG_WARM_NODE],si->cursec[CURSEG_WARM_NODE],si->curzone[CURSEG_WARM_NODE]);seq_printf(s, " - Indir nodes: %d, %d, %d\n",si->curseg[CURSEG_COLD_NODE],si->cursec[CURSEG_COLD_NODE],si->curzone[CURSEG_COLD_NODE]);seq_printf(s, "\n - Valid: %d\n - Dirty: %d\n",si->main_area_segs - si->dirty_count -si->prefree_count - si->free_segs,si->dirty_count);seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n",si->prefree_count, si->free_segs, si->free_secs);seq_printf(s, "CP calls: %d (BG: %d)\n",si->cp_count, si->bg_cp_count);seq_printf(s, " - cp blocks : %u\n", si->meta_count[META_CP]);seq_printf(s, " - sit blocks : %u\n",si->meta_count[META_SIT]);seq_printf(s, " - nat blocks : %u\n",si->meta_count[META_NAT]);seq_printf(s, " - ssa blocks : %u\n",si->meta_count[META_SSA]);seq_printf(s, "GC calls: %d (BG: %d)\n",si->call_count, si->bg_gc);seq_printf(s, " - data segments : %d (%d)\n",si->data_segs, si->bg_data_segs);seq_printf(s, " - node segments : %d (%d)\n",si->node_segs, si->bg_node_segs);seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks,si->bg_data_blks + si->bg_node_blks);seq_printf(s, " - data blocks : %d (%d)\n", si->data_blks,si->bg_data_blks);seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks,si->bg_node_blks);seq_printf(s, "Skipped : atomic write %llu (%llu)\n",si->skipped_atomic_files[BG_GC] +si->skipped_atomic_files[FG_GC],si->skipped_atomic_files[BG_GC]);seq_printf(s, "BG skip : IO: %u, Other: %u\n",si->io_skip_bggc, si->other_skip_bggc);seq_puts(s, "\nExtent Cache:\n");seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",si->hit_largest, si->hit_cached,si->hit_rbtree);seq_printf(s, " - Hit Ratio: %llu%% (%llu / %llu)\n",!si->total_ext ? 0 :div64_u64(si->hit_total * 100, si->total_ext),si->hit_total, si->total_ext);seq_printf(s, " - Inner Struct Count: tree: %d(%d), node: %d\n",si->ext_tree, si->zombie_tree, si->ext_node);seq_puts(s, "\nBalancing F2FS Async:\n");seq_printf(s, " - DIO (R: %4d, W: %4d)\n",si->nr_dio_read, si->nr_dio_write);seq_printf(s, " - IO_R (Data: %4d, Node: %4d, Meta: %4d\n",si->nr_rd_data, si->nr_rd_node, si->nr_rd_meta);seq_printf(s, " - IO_W (CP: %4d, Data: %4d, Flush: (%4d %4d %4d), ""Discard: (%4d %4d)) cmd: %4d undiscard:%4u\n",si->nr_wb_cp_data, si->nr_wb_data,si->nr_flushing, si->nr_flushed,si->flush_list_empty,si->nr_discarding, si->nr_discarded,si->nr_discard_cmd, si->undiscard_blks);seq_printf(s, " - inmem: %4d, atomic IO: %4d (Max. %4d), ""volatile IO: %4d (Max. %4d)\n",si->inmem_pages, si->aw_cnt, si->max_aw_cnt,si->vw_cnt, si->max_vw_cnt);seq_printf(s, " - nodes: %4d in %4d\n",si->ndirty_node, si->node_pages);seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n",si->ndirty_dent, si->ndirty_dirs, si->ndirty_all);seq_printf(s, " - datas: %4d in files:%4d\n",si->ndirty_data, si->ndirty_files);seq_printf(s, " - quota datas: %4d in quota files:%4d\n",si->ndirty_qdata, si->nquota_files);seq_printf(s, " - meta: %4d in %4d\n",si->ndirty_meta, si->meta_pages);seq_printf(s, " - imeta: %4d\n",si->ndirty_imeta);seq_printf(s, " - NATs: %9d/%9d\n - SITs: %9d/%9d\n",si->dirty_nats, si->nats, si->dirty_sits, si->sits);seq_printf(s, " - free_nids: %9d/%9d\n - alloc_nids: %9d\n",si->free_nids, si->avail_nids, si->alloc_nids);seq_puts(s, "\nDistribution of User Blocks:");seq_puts(s, " [ valid | invalid | free ]\n");seq_puts(s, " [");for (j = 0; j < si->util_valid; j++)seq_putc(s, '-');seq_putc(s, '|');for (j = 0; j < si->util_invalid; j++)seq_putc(s, '-');seq_putc(s, '|');for (j = 0; j < si->util_free; j++)seq_putc(s, '-');seq_puts(s, "]\n\n");seq_printf(s, "IPU: %u blocks\n", si->inplace_count);seq_printf(s, "SSR: %u blocks in %u segments\n",si->block_count[SSR], si->segment_count[SSR]);seq_printf(s, "LFS: %u blocks in %u segments\n",si->block_count[LFS], si->segment_count[LFS]);/* segment usage info */update_sit_info(si->sbi);seq_printf(s, "\nBDF: %u, avg. vblocks: %u\n",si->bimodal, si->avg_vblocks);/* memory footprint */update_mem_info(si->sbi);seq_printf(s, "\nMemory: %llu KB\n",(si->base_mem + si->cache_mem + si->page_mem) >> 10);seq_printf(s, " - static: %llu KB\n",si->base_mem >> 10);seq_printf(s, " - cached: %llu KB\n",si->cache_mem >> 10);seq_printf(s, " - paged : %llu KB\n",si->page_mem >> 10);}mutex_unlock(&f2fs_stat_mutex);return 0;
}
初始化f2fs post read processing
int __init f2fs_init_post_read_processing(void)
{bio_post_read_ctx_cache = KMEM_CACHE(bio_post_read_ctx, 0);if (!bio_post_read_ctx_cache)goto fail;bio_post_read_ctx_pool =mempool_create_slab_pool(NUM_PREALLOC_POST_READ_CTXS,bio_post_read_ctx_cache);if (!bio_post_read_ctx_pool)goto fail_free_cache;return 0;fail_free_cache:kmem_cache_destroy(bio_post_read_ctx_cache);
fail:return -ENOMEM;
}struct bio_post_read_ctx {struct bio *bio;struct work_struct work;unsigned int cur_step;unsigned int enabled_steps;
};
f2fs学习三: 文件系统初始化相关推荐
- f2fs学习笔记 - 6. f2fs初始化流程
1.前言 初始流程主要包含f2fs文件系统初始化,以及f2fs文件系统mount 2. init_f2fs_fs init_inodecache 创建f2fs_inode_cache slab描述符 ...
- Docker学习三:Docker 数据管理
前言 本次学习来自于datawhale组队学习: 教程地址为: https://github.com/datawhalechina/team-learning-program/tree/master/ ...
- 转自IBM学习 浅析 Linux 初始化 init 系统,第 3 部分 Systemd
Systemd 的简介和特点 原文链接 https://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/index.html?ca=dr ...
- C#多线程学习(三) 生产者和消费者
C#多线程学习(三) 生产者和消费者 原文链接:http://kb.cnblogs.com/page/42530/ 本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操 ...
- 深度学习三(PyTorch物体检测实战)
深度学习三(PyTorch物体检测实战) 文章目录 深度学习三(PyTorch物体检测实战) 1.网络骨架:Backbone 1.1.神经网络基本组成 1.1.1.卷积层 1.1.2.激活函数层 1. ...
- linux文件系统初始化过程(6)---执行init程序
一.目的 内核加载完initrd文件后,为挂载磁盘文件系统做好了必要的准备工作,包括挂载了sysfs.proc文件系统,加载了磁盘驱动程序驱动程序等.接下来,内核跳转到用户空间的init程序,由ini ...
- 深度学习三巨头共获 2018 年图灵奖(经典重温)!
整理 | 琥珀 出品 | AI科技大本营(ID:rgznai100) 2019 年 3 月 27 日,ACM 宣布,深度学习三位大牛 Yoshua Bengio.Yann LeCun.Geoffrey ...
- C#多线程学习(三) 生产者和消费者 (转载系列)——继续搜索引擎研究
前面说过,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生. ...
- GitHub快速学习-三
title: GitHub快速学习(三) categories: GitHub tags: github abbrlink: 1065435774 date: 2019-06-27 14:34:28 ...
最新文章
- unity 纹理压缩格式‘_[2018.1]Unity贴图压缩格式设置
- 使用Git向GitHub上传代码
- FileChannel与ByteBuffer的使用示例
- 关机时无人照管更新正在运行_路辉物流设备:无人化分拣作业驱动物流业降本增效...
- SSH报错:packet_write_wait: Connection to xxx Broken pipe 解决
- 【项目实战】基于 springboot + mybatis + mysql 的电脑商城项目(附源码)
- 如何在服务器上上传手游源码,【仙变3手游】跨服服务端游戏源码+架设教程+双端+后台...
- 基于PHP+小程序(MINA框架)+Mysql数据库的汽车维修保养小程序系统设计与实现
- 微信HOOK-微信逆向-微信公众号爬虫系统
- 单词记忆 词根词缀记忆 总结
- ONLYOFFICE 如何连接集成到 Wordpress 上
- 英语不规则动词变化时态变化表
- android xml画斜线,API返回XML引号通过反斜线
- 如何一次性查询千百个顺丰快递的详细物流信息
- linux下DNS配置及域名解析服务,linux DNS域名解析服务
- 从《我要投资》,看藏在“对立面”里的创业正解
- hd530黑苹果硬解_解决黑苹果HD3000核显 VGA和HDMI外接显示器无反应问题
- 戴尔计算机主机型号,戴尔电脑在哪看型号_戴尔电脑型号怎么看
- LIS2MDL磁力计驱动
- 案例精选 | 志翔科技:安全与高效并重 构筑芯片行业数据安全堡垒