系统调用

什么是系统调用:

操作系统实现并提供给外部应用程序的编程接口。(Application Programming Interface,API)。是应用程序同系统之间数据交互的桥梁。

C标准函数和系统函数调用关系。一个helloworld如何打印到屏幕。

 

C标准库文件IO函数。

fopen、fclose、fseek、fgets、fputs、fread、fwrite......

r 只读、 r+读写

w只写并截断为0、 w+读写并截断为0

a追加只写、 a+追加读写

open/close函数

函数原型:头文件 <unistd.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

int close(int fd);

常用参数

O_RDONLY、O_WRONLY、O_RDWR

O_APPEND、O_CREAT、O_EXCL(判断文件是否存在)、 O_TRUNC(文件截断为0)、 O_NONBLOCK

使用头文件:<fcntl.h>

open常见错误:

1. 打开文件不存在

2. 以写方式打开只读文件(打开文件没有对应权限)

3. 以只写方式打开目录

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4.  
  5. int main()
  6. {
  7. int fd = open("./test.txt",O_RDONLY);
  8. printf("fd = %d\n",fd);
  9.  
  10. close(fd);
  11.  
  12. return ;
  13. }

O_CREAT 才需要指定第三个参数,文件权限还需要依赖于掩码umask,mode  & ~umask

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4.  
  5. int main()
  6. {
  7. int fd = open("./text.txt",O_RDONLY | O_CREAT, ); // 权限八进制,
  8. printf("fd = %d",fd);
  9.  
  10. close(fd);
  11.  
  12. return ;
  13. }
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5.  
  6. int main()
  7. {
  8. int fd = open("./textt.txt",O_RDONLY);
  9. printf("fd = %d",fd);
  10. printf("error: %d",errno);
  11.  
  12. close(fd);
  13.  
  14. return ;
  15. }

文件描述符:

PCB进程控制块

可使用命令locate sched.h查看位置:        /usr/src/linux-headers-3.16.0-30/include/linux/sched.h

struct task_struct { 结构体

  1. struct task_struct {
  2. #ifdef CONFIG_THREAD_INFO_IN_TASK
  3. /*
  4. * For reasons of header soup (see current_thread_info()), this
  5. * must be the first element of task_struct.
  6. */
  7. struct thread_info thread_info;
  8. #endif
  9. /* -1 unrunnable, 0 runnable, >0 stopped: */
  10. volatile long state;
  11.  
  12. /*
  13. * This begins the randomizable portion of task_struct. Only
  14. * scheduling-critical items should be added above here.
  15. */
  16. randomized_struct_fields_start
  17.  
  18. void *stack;
  19. atomic_t usage;
  20. /* Per task flags (PF_*), defined further below: */
  21. unsigned int flags;
  22. unsigned int ptrace;
  23.  
  24. #ifdef CONFIG_SMP
  25. struct llist_node wake_entry;
  26. int on_cpu;
  27. #ifdef CONFIG_THREAD_INFO_IN_TASK
  28. /* Current CPU: */
  29. unsigned int cpu;
  30. #endif
  31. unsigned int wakee_flips;
  32. unsigned long wakee_flip_decay_ts;
  33. struct task_struct *last_wakee;
  34.  
  35. int wake_cpu;
  36. #endif
  37. int on_rq;
  38.  
  39. int prio;
  40. int static_prio;
  41. int normal_prio;
  42. unsigned int rt_priority;
  43.  
  44. const struct sched_class *sched_class;
  45. struct sched_entity se;
  46. struct sched_rt_entity rt;
  47. #ifdef CONFIG_CGROUP_SCHED
  48. struct task_group *sched_task_group;
  49. #endif
  50. struct sched_dl_entity dl;
  51.  
  52. #ifdef CONFIG_PREEMPT_NOTIFIERS
  53. /* List of struct preempt_notifier: */
  54. struct hlist_head preempt_notifiers;
  55. #endif
  56.  
  57. #ifdef CONFIG_BLK_DEV_IO_TRACE
  58. unsigned int btrace_seq;
  59. #endif
  60.  
  61. unsigned int policy;
  62. int nr_cpus_allowed;
  63. cpumask_t cpus_allowed;
  64.  
  65. #ifdef CONFIG_PREEMPT_RCU
  66. int rcu_read_lock_nesting;
  67. union rcu_special rcu_read_unlock_special;
  68. struct list_head rcu_node_entry;
  69. struct rcu_node *rcu_blocked_node;
  70. #endif /* #ifdef CONFIG_PREEMPT_RCU */
  71.  
  72. #ifdef CONFIG_TASKS_RCU
  73. unsigned long rcu_tasks_nvcsw;
  74. u8 rcu_tasks_holdout;
  75. u8 rcu_tasks_idx;
  76. int rcu_tasks_idle_cpu;
  77. struct list_head rcu_tasks_holdout_list;
  78. #endif /* #ifdef CONFIG_TASKS_RCU */
  79.  
  80. struct sched_info sched_info;
  81.  
  82. struct list_head tasks;
  83. #ifdef CONFIG_SMP
  84. struct plist_node pushable_tasks;
  85. struct rb_node pushable_dl_tasks;
  86. #endif
  87.  
  88. struct mm_struct *mm;
  89. struct mm_struct *active_mm;
  90.  
  91. /* Per-thread vma caching: */
  92. struct vmacache vmacache;
  93.  
  94. #ifdef SPLIT_RSS_COUNTING
  95. struct task_rss_stat rss_stat;
  96. #endif
  97. int exit_state;
  98. int exit_code;
  99. int exit_signal;
  100. /* The signal sent when the parent dies: */
  101. int pdeath_signal;
  102. /* JOBCTL_*, siglock protected: */
  103. unsigned long jobctl;
  104.  
  105. /* Used for emulating ABI behavior of previous Linux versions: */
  106. unsigned int personality;
  107.  
  108. /* Scheduler bits, serialized by scheduler locks: */
  109. unsigned sched_reset_on_fork:;
  110. unsigned sched_contributes_to_load:;
  111. unsigned sched_migrated:;
  112. unsigned sched_remote_wakeup:;
  113. /* Force alignment to the next boundary: */
  114. unsigned :;
  115.  
  116. /* Unserialized, strictly 'current' */
  117.  
  118. /* Bit to tell LSMs we're in execve(): */
  119. unsigned in_execve:;
  120. unsigned in_iowait:;
  121. #ifndef TIF_RESTORE_SIGMASK
  122. unsigned restore_sigmask:;
  123. #endif
  124. #ifdef CONFIG_MEMCG
  125. unsigned memcg_may_oom:;
  126. #ifndef CONFIG_SLOB
  127. unsigned memcg_kmem_skip_account:;
  128. #endif
  129. #endif
  130. #ifdef CONFIG_COMPAT_BRK
  131. unsigned brk_randomized:;
  132. #endif
  133. #ifdef CONFIG_CGROUPS
  134. /* disallow userland-initiated cgroup migration */
  135. unsigned no_cgroup_migration:;
  136. #endif
  137.  
  138. unsigned long atomic_flags; /* Flags requiring atomic access. */
  139.  
  140. struct restart_block restart_block;
  141.  
  142. pid_t pid;
  143. pid_t tgid;
  144.  
  145. #ifdef CONFIG_CC_STACKPROTECTOR
  146. /* Canary value for the -fstack-protector GCC feature: */
  147. unsigned long stack_canary;
  148. #endif
  149. /*
  150. * Pointers to the (original) parent process, youngest child, younger sibling,
  151. * older sibling, respectively. (p->father can be replaced with
  152. * p->real_parent->pid)
  153. */
  154.  
  155. /* Real parent process: */
  156. struct task_struct __rcu *real_parent;
  157.  
  158. /* Recipient of SIGCHLD, wait4() reports: */
  159. struct task_struct __rcu *parent;
  160.  
  161. /*
  162. * Children/sibling form the list of natural children:
  163. */
  164. struct list_head children;
  165. struct list_head sibling;
  166. struct task_struct *group_leader;
  167.  
  168. /*
  169. * 'ptraced' is the list of tasks this task is using ptrace() on.
  170. *
  171. * This includes both natural children and PTRACE_ATTACH targets.
  172. * 'ptrace_entry' is this task's link on the p->parent->ptraced list.
  173. */
  174. struct list_head ptraced;
  175. struct list_head ptrace_entry;
  176.  
  177. /* PID/PID hash table linkage. */
  178. struct pid_link pids[PIDTYPE_MAX];
  179. struct list_head thread_group;
  180. struct list_head thread_node;
  181.  
  182. struct completion *vfork_done;
  183.  
  184. /* CLONE_CHILD_SETTID: */
  185. int __user *set_child_tid;
  186.  
  187. /* CLONE_CHILD_CLEARTID: */
  188. int __user *clear_child_tid;
  189.  
  190. u64 utime;
  191. u64 stime;
  192. #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
  193. u64 utimescaled;
  194. u64 stimescaled;
  195. #endif
  196. u64 gtime;
  197. struct prev_cputime prev_cputime;
  198. #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
  199. struct vtime vtime;
  200. #endif
  201.  
  202. #ifdef CONFIG_NO_HZ_FULL
  203. atomic_t tick_dep_mask;
  204. #endif
  205. /* Context switch counts: */
  206. unsigned long nvcsw;
  207. unsigned long nivcsw;
  208.  
  209. /* Monotonic time in nsecs: */
  210. u64 start_time;
  211.  
  212. /* Boot based time in nsecs: */
  213. u64 real_start_time;
  214.  
  215. /* MM fault and swap info: this can arguably be seen as either mm-specific or thread-specific: */
  216. unsigned long min_flt;
  217. unsigned long maj_flt;
  218.  
  219. #ifdef CONFIG_POSIX_TIMERS
  220. struct task_cputime cputime_expires;
  221. struct list_head cpu_timers[];
  222. #endif
  223.  
  224. /* Process credentials: */
  225.  
  226. /* Tracer's credentials at attach: */
  227. const struct cred __rcu *ptracer_cred;
  228.  
  229. /* Objective and real subjective task credentials (COW): */
  230. const struct cred __rcu *real_cred;
  231.  
  232. /* Effective (overridable) subjective task credentials (COW): */
  233. const struct cred __rcu *cred;
  234.  
  235. /*
  236. * executable name, excluding path.
  237. *
  238. * - normally initialized setup_new_exec()
  239. * - access it with [gs]et_task_comm()
  240. * - lock it with task_lock()
  241. */
  242. char comm[TASK_COMM_LEN];
  243.  
  244. struct nameidata *nameidata;
  245.  
  246. #ifdef CONFIG_SYSVIPC
  247. struct sysv_sem sysvsem;
  248. struct sysv_shm sysvshm;
  249. #endif
  250. #ifdef CONFIG_DETECT_HUNG_TASK
  251. unsigned long last_switch_count;
  252. #endif
  253. /* Filesystem information: */
  254. struct fs_struct *fs;
  255.  
  256. /* Open file information: */
  257. struct files_struct *files;
  258.  
  259. /* Namespaces: */
  260. struct nsproxy *nsproxy;
  261.  
  262. /* Signal handlers: */
  263. struct signal_struct *signal;
  264. struct sighand_struct *sighand;
  265. sigset_t blocked;
  266. sigset_t real_blocked;
  267. /* Restored if set_restore_sigmask() was used: */
  268. sigset_t saved_sigmask;
  269. struct sigpending pending;
  270. unsigned long sas_ss_sp;
  271. size_t sas_ss_size;
  272. unsigned int sas_ss_flags;
  273.  
  274. struct callback_head *task_works;
  275.  
  276. struct audit_context *audit_context;
  277. #ifdef CONFIG_AUDITSYSCALL
  278. kuid_t loginuid;
  279. unsigned int sessionid;
  280. #endif
  281. struct seccomp seccomp;
  282.  
  283. /* Thread group tracking: */
  284. u32 parent_exec_id;
  285. u32 self_exec_id;
  286.  
  287. /* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */
  288. spinlock_t alloc_lock;
  289.  
  290. /* Protection of the PI data structures: */
  291. raw_spinlock_t pi_lock;
  292.  
  293. struct wake_q_node wake_q;
  294.  
  295. #ifdef CONFIG_RT_MUTEXES
  296. /* PI waiters blocked on a rt_mutex held by this task: */
  297. struct rb_root_cached pi_waiters;
  298. /* Updated under owner's pi_lock and rq lock */
  299. struct task_struct *pi_top_task;
  300. /* Deadlock detection and priority inheritance handling: */
  301. struct rt_mutex_waiter *pi_blocked_on;
  302. #endif
  303.  
  304. #ifdef CONFIG_DEBUG_MUTEXES
  305. /* Mutex deadlock detection: */
  306. struct mutex_waiter *blocked_on;
  307. #endif
  308.  
  309. #ifdef CONFIG_TRACE_IRQFLAGS
  310. unsigned int irq_events;
  311. unsigned long hardirq_enable_ip;
  312. unsigned long hardirq_disable_ip;
  313. unsigned int hardirq_enable_event;
  314. unsigned int hardirq_disable_event;
  315. int hardirqs_enabled;
  316. int hardirq_context;
  317. unsigned long softirq_disable_ip;
  318. unsigned long softirq_enable_ip;
  319. unsigned int softirq_disable_event;
  320. unsigned int softirq_enable_event;
  321. int softirqs_enabled;
  322. int softirq_context;
  323. #endif
  324.  
  325. #ifdef CONFIG_LOCKDEP
  326. # define MAX_LOCK_DEPTH 48UL
  327. u64 curr_chain_key;
  328. int lockdep_depth;
  329. unsigned int lockdep_recursion;
  330. struct held_lock held_locks[MAX_LOCK_DEPTH];
  331. #endif
  332.  
  333. #ifdef CONFIG_UBSAN
  334. unsigned int in_ubsan;
  335. #endif
  336.  
  337. /* Journalling filesystem info: */
  338. void *journal_info;
  339.  
  340. /* Stacked block device info: */
  341. struct bio_list *bio_list;
  342.  
  343. #ifdef CONFIG_BLOCK
  344. /* Stack plugging: */
  345. struct blk_plug *plug;
  346. #endif
  347.  
  348. /* VM state: */
  349. struct reclaim_state *reclaim_state;
  350.  
  351. struct backing_dev_info *backing_dev_info;
  352.  
  353. struct io_context *io_context;
  354.  
  355. /* Ptrace state: */
  356. unsigned long ptrace_message;
  357. siginfo_t *last_siginfo;
  358.  
  359. struct task_io_accounting ioac;
  360. #ifdef CONFIG_TASK_XACCT
  361. /* Accumulated RSS usage: */
  362. u64 acct_rss_mem1;
  363. /* Accumulated virtual memory usage: */
  364. u64 acct_vm_mem1;
  365. /* stime + utime since last update: */
  366. u64 acct_timexpd;
  367. #endif
  368. #ifdef CONFIG_CPUSETS
  369. /* Protected by ->alloc_lock: */
  370. nodemask_t mems_allowed;
  371. /* Seqence number to catch updates: */
  372. seqcount_t mems_allowed_seq;
  373. int cpuset_mem_spread_rotor;
  374. int cpuset_slab_spread_rotor;
  375. #endif
  376. #ifdef CONFIG_CGROUPS
  377. /* Control Group info protected by css_set_lock: */
  378. struct css_set __rcu *cgroups;
  379. /* cg_list protected by css_set_lock and tsk->alloc_lock: */
  380. struct list_head cg_list;
  381. #endif
  382. #ifdef CONFIG_INTEL_RDT
  383. u32 closid;
  384. u32 rmid;
  385. #endif
  386. #ifdef CONFIG_FUTEX
  387. struct robust_list_head __user *robust_list;
  388. #ifdef CONFIG_COMPAT
  389. struct compat_robust_list_head __user *compat_robust_list;
  390. #endif
  391. struct list_head pi_state_list;
  392. struct futex_pi_state *pi_state_cache;
  393. #endif
  394. #ifdef CONFIG_PERF_EVENTS
  395. struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts];
  396. struct mutex perf_event_mutex;
  397. struct list_head perf_event_list;
  398. #endif
  399. #ifdef CONFIG_DEBUG_PREEMPT
  400. unsigned long preempt_disable_ip;
  401. #endif
  402. #ifdef CONFIG_NUMA
  403. /* Protected by alloc_lock: */
  404. struct mempolicy *mempolicy;
  405. short il_prev;
  406. short pref_node_fork;
  407. #endif
  408. #ifdef CONFIG_NUMA_BALANCING
  409. int numa_scan_seq;
  410. unsigned int numa_scan_period;
  411. unsigned int numa_scan_period_max;
  412. int numa_preferred_nid;
  413. unsigned long numa_migrate_retry;
  414. /* Migration stamp: */
  415. u64 node_stamp;
  416. u64 last_task_numa_placement;
  417. u64 last_sum_exec_runtime;
  418. struct callback_head numa_work;
  419.  
  420. struct list_head numa_entry;
  421. struct numa_group *numa_group;
  422.  
  423. /*
  424. * numa_faults is an array split into four regions:
  425. * faults_memory, faults_cpu, faults_memory_buffer, faults_cpu_buffer
  426. * in this precise order.
  427. *
  428. * faults_memory: Exponential decaying average of faults on a per-node
  429. * basis. Scheduling placement decisions are made based on these
  430. * counts. The values remain static for the duration of a PTE scan.
  431. * faults_cpu: Track the nodes the process was running on when a NUMA
  432. * hinting fault was incurred.
  433. * faults_memory_buffer and faults_cpu_buffer: Record faults per node
  434. * during the current scan window. When the scan completes, the counts
  435. * in faults_memory and faults_cpu decay and these values are copied.
  436. */
  437. unsigned long *numa_faults;
  438. unsigned long total_numa_faults;
  439.  
  440. /*
  441. * numa_faults_locality tracks if faults recorded during the last
  442. * scan window were remote/local or failed to migrate. The task scan
  443. * period is adapted based on the locality of the faults with different
  444. * weights depending on whether they were shared or private faults
  445. */
  446. unsigned long numa_faults_locality[];
  447.  
  448. unsigned long numa_pages_migrated;
  449. #endif /* CONFIG_NUMA_BALANCING */
  450.  
  451. struct tlbflush_unmap_batch tlb_ubc;
  452.  
  453. struct rcu_head rcu;
  454.  
  455. /* Cache last used pipe for splice(): */
  456. struct pipe_inode_info *splice_pipe;
  457.  
  458. struct page_frag task_frag;
  459.  
  460. #ifdef CONFIG_TASK_DELAY_ACCT
  461. struct task_delay_info *delays;
  462. #endif
  463.  
  464. #ifdef CONFIG_FAULT_INJECTION
  465. int make_it_fail;
  466. unsigned int fail_nth;
  467. #endif
  468. /*
  469. * When (nr_dirtied >= nr_dirtied_pause), it's time to call
  470. * balance_dirty_pages() for a dirty throttling pause:
  471. */
  472. int nr_dirtied;
  473. int nr_dirtied_pause;
  474. /* Start of a write-and-pause period: */
  475. unsigned long dirty_paused_when;
  476.  
  477. #ifdef CONFIG_LATENCYTOP
  478. int latency_record_count;
  479. struct latency_record latency_record[LT_SAVECOUNT];
  480. #endif
  481. /*
  482. * Time slack values; these are used to round up poll() and
  483. * select() etc timeout values. These are in nanoseconds.
  484. */
  485. u64 timer_slack_ns;
  486. u64 default_timer_slack_ns;
  487.  
  488. #ifdef CONFIG_KASAN
  489. unsigned int kasan_depth;
  490. #endif
  491.  
  492. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  493. /* Index of current stored address in ret_stack: */
  494. int curr_ret_stack;
  495.  
  496. /* Stack of return addresses for return function tracing: */
  497. struct ftrace_ret_stack *ret_stack;
  498.  
  499. /* Timestamp for last schedule: */
  500. unsigned long long ftrace_timestamp;
  501.  
  502. /*
  503. * Number of functions that haven't been traced
  504. * because of depth overrun:
  505. */
  506. atomic_t trace_overrun;
  507.  
  508. /* Pause tracing: */
  509. atomic_t tracing_graph_pause;
  510. #endif
  511.  
  512. #ifdef CONFIG_TRACING
  513. /* State flags for use by tracers: */
  514. unsigned long trace;
  515.  
  516. /* Bitmask and counter of trace recursion: */
  517. unsigned long trace_recursion;
  518. #endif /* CONFIG_TRACING */
  519.  
  520. #ifdef CONFIG_KCOV
  521. /* Coverage collection mode enabled for this task (0 if disabled): */
  522. enum kcov_mode kcov_mode;
  523.  
  524. /* Size of the kcov_area: */
  525. unsigned int kcov_size;
  526.  
  527. /* Buffer for coverage collection: */
  528. void *kcov_area;
  529.  
  530. /* KCOV descriptor wired with this task or NULL: */
  531. struct kcov *kcov;
  532. #endif
  533.  
  534. #ifdef CONFIG_MEMCG
  535. struct mem_cgroup *memcg_in_oom;
  536. gfp_t memcg_oom_gfp_mask;
  537. int memcg_oom_order;
  538.  
  539. /* Number of pages to reclaim on returning to userland: */
  540. unsigned int memcg_nr_pages_over_high;
  541. #endif
  542.  
  543. #ifdef CONFIG_UPROBES
  544. struct uprobe_task *utask;
  545. #endif
  546. #if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE)
  547. unsigned int sequential_io;
  548. unsigned int sequential_io_avg;
  549. #endif
  550. #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
  551. unsigned long task_state_change;
  552. #endif
  553. int pagefault_disabled;
  554. #ifdef CONFIG_MMU
  555. struct task_struct *oom_reaper_list;
  556. #endif
  557. #ifdef CONFIG_VMAP_STACK
  558. struct vm_struct *stack_vm_area;
  559. #endif
  560. #ifdef CONFIG_THREAD_INFO_IN_TASK
  561. /* A live task holds one reference: */
  562. atomic_t stack_refcount;
  563. #endif
  564. #ifdef CONFIG_LIVEPATCH
  565. int patch_state;
  566. #endif
  567. #ifdef CONFIG_SECURITY
  568. /* Used by LSM modules for access restriction: */
  569. void *security;
  570. #endif
  571.  
  572. /*
  573. * New fields for task_struct should be added above here, so that
  574. * they are included in the randomized portion of task_struct.
  575. */
  576. randomized_struct_fields_end
  577.  
  578. /* CPU-specific state of this task: */
  579. struct thread_struct thread;
  580.  
  581. /*
  582. * WARNING: on x86, 'thread_struct' contains a variable-sized
  583. * structure. It *MUST* be at the end of 'task_struct'.
  584. *
  585. * Do not put anything below here!
  586. */
  587. };

struct task_struct

每当执行一个程序,运行./a.out,它就会产生这样一个0-4G的虚拟内存地址空间 

文件描述符表

结构体PCB 的成员变量file_struct *file 指向文件描述符表。

从应用程序使用角度,该指针可理解记忆成一个字符指针数组,下标0/1/2/3/4...找到文件结构体。

本质是一个键值对0、1、2...都分别对应具体地址。但键值对使用的特性是自动映射,我们只操作键不直接使用值。

新打开文件返回文件描述符表中未使用的最小文件描述符。

STDIN_FILENO       0

STDOUT_FILENO  1

STDERR_FILENO      2

FILE结构体

主要包含文件描述符、文件读写位置、IO缓冲区三部分内容。

struct file {

...

文件的偏移量;

文件的访问权限;

文件的打开标志;

文件内核缓冲区的首地址;

struct operations * f_op;

...

};

查看方法:

(1) /usr/src/linux-headers-3.16.0-30/include/linux/fs.h

(2) lxr:LXR( Linux超文本交叉代码检索工具)    

  1. Linux超文本交叉代码检索工具LXRLinux Cross Reference),是由挪威奥斯陆大学数学系Arne Georg GleditschPer Kristian Gjermshus编写的。这个工具实际上运行在Linux或者UNIX平台下,通过对源代码中的所有符号建立索引,从而可以方便的检索任何一个符号,包括函数、外部变量、文件名、宏定义等等。不仅仅是针对Linux源代码,对于C语言的其他大型的项目,都可以建立其lxr站点,以提供开发者查询代码,以及后继开发者学习代码。
  2.   目前的lxr是专门为Linux下面的Apache服务器设计的,通过运行perl脚本,检索在安装时根据需要建立的源代码索引文件,将数据发送到网络客户端的Web浏览器上。任何一种平台上的Web浏览器都可以访问,这就方便了习惯在Windows平台下工作的用户。
  3. 关于lxr的英文网站为http://lxr.linux.no/,在中国Linux论坛http://www.linuxforum.net上有其镜象。
  4.  
  5. 如何建立自己的LXR网站?
  6. 直接通过http://lxr.linux.no/lxr-0.3.tar.gz,下载lxr的tarball形式的安装包。
  7. 另外,因为lxr使用glimpse作为整个项目中文本的搜索工具,因此还需要下载glimpse
  8. 网址在http://glimpse.cs.arizona.edu
  9. ,下载glimpse-4.12..bin.Linux-2.2.--i686.tar.gz
  10. 也可以使用更新的版本。 下载以后按照说明进行安装和配置,就可以建立自己的LXR网站。
  11. 如果你上网很方便,就可以直接从http://lxr.linux.no/网站查询你需要的各种源码信息。
  12.  
  13. 目前,可用的lxr网址有:
  14. linux源码浏览:http://lxr.free-electrons.com/

LXR介绍

     百度 lxr → lxr.oss.org.cn → 选择内核版本(如3.10) → 点击File Search进行搜索

→ 关键字:“include/linux/fs.h” → Ctrl+F 查找 “struct file {”

→ 得到文件内核中结构体定义

→ “struct file_operations”文件内容操作函数指针

→ “struct inode_operations”文件属性操作函数指针

最大打开文件数

一个进程默认打开文件的个数1024。

命令查看ulimit -a 查看open files 对应值。默认为1024

  1. gec@ubuntu:~/myshare/文件IO$ ulimit -a
  2. core file size (blocks, -c)
  3. data seg size (kbytes, -d) unlimited
  4. scheduling priority (-e)
  5. file size (blocks, -f) unlimited
  6. pending signals (-i)
  7. max locked memory (kbytes, -l)
  8. max memory size (kbytes, -m) unlimited
  9. open files (-n) 1024
  10. pipe size ( bytes, -p)
  11. POSIX message queues (bytes, -q)
  12. real-time priority (-r)
  13. stack size (kbytes, -s)
  14. cpu time (seconds, -t) unlimited
  15. max user processes (-u)
  16. virtual memory (kbytes, -v) unlimited
  17. file locks (-x) unlimited

可以使用ulimit -n 4096 修改

当然也可以通过修改系统配置文件永久修改该值,但是不建议这样操作。

cat /proc/sys/fs/file-max可以查看该电脑最大可以打开的文件个数。受内存大小影响。

  1. gec@ubuntu:~/myshare/文件IO$ cat /proc/sys/fs/file-max

read/write函数

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

 

read与write函数原型类似。使用时需注意:read/write函数的第三个参数。

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5.  
  6. int main()
  7. {
  8. char buf[] = {};
  9. int ret = ;
  10. int fd = open("./open.c",O_RDONLY);
  11.  
  12. printf("fd = %d",fd);
  13. printf("error: %d",errno);
  14.  
  15. while((ret= read(fd,buf,sizeof(buf))) != ) {
  16. write(STDOUT_FILENO,buf,ret);
  17.  
  18. }
  19.  
  20. close(fd);
  21.  
  22. return ;
  23. }

练习:编写程序实现简单的cp功能。

  1. /*
  2. *./mycp src dst 命令行参数实现简单的cp命令
  3. */
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <stdio.h>
  8.  
  9. char buf[];
  10.  
  11. int main(int argc, char *argv[])
  12. {
  13. int src, dst;
  14. int n;
  15.  
  16. src = open(argv[], O_RDONLY); //只读打开源文件
  17. if(src < ){
  18. perror("open src error");
  19. exit();
  20. }
  21. //只写方式打开,覆盖原文件内容,不存在则创建,rw-r--r--
  22. dst = open(argv[], O_WRONLY|O_TRUNC|O_CREAT, );
  23. if(src < ){
  24. perror("open dst error");
  25. exit();
  26. }
  27. while((n = read(src, buf, ))){
  28. if(n < ){
  29. perror("read src error");
  30. exit();
  31. }
  32. write(dst, buf, n); //不应写出1024, 读多少写多少
  33. }
  34.  
  35. close(src);
  36. close(dst);
  37.  
  38. return ;
  39. }

程序比较:如果一个只读一个字节实现文件拷贝,使用read、write效率高,还是使用对应的标库函数效率高呢?

用系统函数read和write 一次一个字节的读写操作,和标准库函数 fgetc, fputc 一次一个字节读写

从理论上来看,好像 fgetc, fputc 的执行效率要比 read,write ,因为标库函数 底层还是调用系统函数

  1. #include <string.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6.  
  7. #define N 1
  8.  
  9. int main(int argc, char *argv[])
  10. {
  11. int fd, fd_out;
  12. int n;
  13. char buf[N];
  14.  
  15. fd = open("dict.txt", O_RDONLY);
  16. if(fd < ){
  17. perror("open dict.txt error");
  18. exit();
  19. }
  20.  
  21. fd_out = open("dict.cp", O_WRONLY|O_CREAT|O_TRUNC, );
  22. if(fd < ){
  23. perror("open dict.cp error");
  24. exit();
  25. }
  26.  
  27. while((n = read(fd, buf, N))){
  28. if(n < ){
  29. perror("read error");
  30. exit();
  31. }
  32. write(fd_out, buf, n);
  33. }
  34.  
  35. close(fd);
  36. close(fd_out);
  37.  
  38. return ;
  39. }

系统调用read,write

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6. FILE *fp, *fp_out;
  7. int n;
  8.  
  9. fp = fopen("dict.txt", "r");
  10. if(fp == NULL){
  11. perror("fopen error");
  12. exit();
  13. }
  14.  
  15. fp_out = fopen("dict.cp", "w");
  16. if(fp == NULL){
  17. perror("fopen error");
  18. exit();
  19. }
  20.  
  21. while((n = fgetc(fp)) != EOF){
  22. fputc(n, fp_out);
  23. }
  24.  
  25. fclose(fp);
  26. fclose(fp_out);
  27.  
  28. return ;
  29. }

标库调用fgetc,fputc

但是实际运行 标库函数运行的效率明显高于系统调用,这是因为系统的一个预读入和缓输出的机制

标库函数用户区有一个默认 4096 字节的缓冲区,不会每一次调用都去触发底层的系统调用,而系统调用函数用户区没有缓冲区机制,它的缓冲区大小有我们在程序中指定,

所以一个字节一个字节的读写操作的时候,标库函数要比系统调用节省很多次数据从用户区到内核区的的拷贝,而这一块是很耗费时间的。

strace命令

shell中使用strace命令跟踪程序执行,查看调用的系统函数

缓冲区

read、write函数常常被称为Unbuffered I/O。指的是无用户及缓冲区。但不保证不使用内核缓冲区。

预读入缓输出

错误处理函数:

错误号:errno

  1. perror函数: void perror(const char *s);
  2.  
  3. strerror函数: char *strerror(int errnum);

还有一个函数 strerror() 了解一下

查看错误号:

  1. /usr/include/asm-generic/errno-base.h
  2.  
  3. /usr/include/asm-generic/errno.h
  1. #include <unistd.h> //read write
  2. #include <fcntl.h> //open close O_WRONLY O_RDONLY O_CREAT O_RDWR
  3. #include <stdlib.h> //exit
  4. #include <errno.h>
  5. #include <stdio.h> //perror
  6. #include <string.h>
  7.  
  8. int main(void)
  9. {
  10. int fd;
  11. #if 1
  12. //打开文件不存在
  13. fd = open("test", O_RDONLY | O_CREAT);
  14. if(fd < ){
  15. printf("errno = %d\n", errno);
  16. // perror("open test error");
  17. printf("open test error: %s\n" , strerror(errno));
  18.  
  19. //printf("open test error\n");
  20. exit();
  21. }
  22. #elif 0
  23. //打开的文件没有对应权限(以只写方式打开一个只有读权限的文件)
  24. fd = open("test", O_WRONLY); //O_RDWR也是错误的
  25. if(fd < ){
  26. printf("errno = %d\n", errno);
  27. perror("open test error");
  28. //printf("open test error\n");
  29. exit();
  30. }
  31.  
  32. #endif
  33. #if 0
  34. //以写方式打开一个目录
  35. fd = open("testdir", O_RDWR); //O_WRONLY也是错的
  36. if(fd < ){
  37. perror("open testdir error");
  38. exit();
  39. }
  40. #endif
  41.  
  42. return ;
  43. }

阻塞、非阻塞

读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞,至于会阻塞多长时间也是不确定的,如果一直没有数据到达就一直阻塞在那里。同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定。

现在明确一下阻塞(Block)这个概念。当进程调用一个阻塞的系统函数时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep指定的睡眠时间到了)它才有可能继续运行。与睡眠状态相对的是运行(Running)状态,在Linux内核中,处于运行状态的进程分为两种情况:

正在被调度执行。CPU处于该进程的上下文环境中,程序计数器(eip)里保存着该进程的指令地址,通用寄存器里保存着该进程运算过程的中间结果,正在执行该进程的指令,正在读写该进程的地址空间。

就绪状态。该进程不需要等待什么事件发生,随时都可以执行,但CPU暂时还在执行另一个进程,所以该进程在一个就绪队列中等待被内核调度。系统中可能同时有多个就绪的进程,那么该调度谁执行呢?内核的调度算法是基于优先级和时间片的,而且会根据每个进程的运行情况动态调整它的优先级和时间片,让每个进程都能比较公平地得到机会执行,同时要兼顾用户体验,不能让和用户交互的进程响应太慢。

阻塞读终端:【block_readtty.c】

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4.  
  5. //hello worl d \n
  6.  
  7. int main(void)
  8. {
  9. char buf[];
  10. int n;
  11.  
  12. n = read(STDIN_FILENO, buf, ); // #define STDIN_FILENO 0 STDOUT_FILENO 1 STDERR_FILENO 2
  13. if(n < ){
  14. perror("read STDIN_FILENO");
  15. //printf("%d", errno);
  16. exit();
  17. }
  18. write(STDOUT_FILENO, buf, n);
  19.  
  20. return ;
  21. }

非阻塞读终端 【nonblock_readtty.c】

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #define MSG_TRY "try again\n"
  9.  
  10. int main(void)
  11. {
  12. char buf[];
  13. int fd, n;
  14.  
  15. fd = open("/dev/tty", O_RDONLY|O_NONBLOCK); //使用O_NONBLOCK标志设置非阻塞读终端
  16. if(fd < ){
  17. perror("open /dev/tty");
  18. exit();
  19. }
  20. tryagain:
  21.  
  22. n = read(fd, buf, ); //-1 (1) 出错 errno==EAGAIN或者EWOULDBLOCK
  23.  
  24. if(n < ){
  25. //由于open时指定了O_NONBLOCK标志,read读设备,没有数据到达返回-1,同时将errno设置为EAGAIN或EWOULDBLOCK
  26. if(errno != EAGAIN){ //也可以是 if(error != EWOULDBLOCK)两个宏值相同
  27. perror("read /dev/tty");
  28. exit();
  29. }
  30. sleep();
  31. write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
  32. goto tryagain;
  33. }
  34. write(STDOUT_FILENO, buf, n);
  35. close(fd);
  36.  
  37. return ;
  38. }

非阻塞读终端和等待超时【nonblock_timeout.c】

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <errno.h>
  6. #include <string.h>
  7.  
  8. #define MSG_TRY "try again\n"
  9. #define MSG_TIMEOUT "time out\n"
  10.  
  11. int main(void)
  12. {
  13. char buf[];
  14. int fd, n, i;
  15.  
  16. fd = open("/dev/tty", O_RDONLY|O_NONBLOCK); // 重新打开 终端设备,默认是阻塞的,指定非阻塞打开方式
  17. if(fd < ){
  18. perror("open /dev/tty");
  19. exit();
  20. }
  21. printf("open /dev/tty ok... %d\n", fd);
  22.  
  23. for (i = ; i < ; i++){
  24. n = read(fd, buf, );
  25. if(n > ){ //说明读到了东西
  26. break;
  27. }
  28. if(errno != EAGAIN){ //EWOULDBLK
  29. perror("read /dev/tty");
  30. exit();
  31. }
  32. sleep();
  33. write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
  34. }
  35.  
  36. if(i == ){
  37. write(STDOUT_FILENO, MSG_TIMEOUT, strlen(MSG_TIMEOUT));
  38. }else{
  39. write(STDOUT_FILENO, buf, n);
  40. }
  41.  
  42. close(fd);
  43.  
  44. return ;
  45. }

注意,阻塞与非阻塞是对于文件而言的。而不是read、write等的属性。read终端,默认阻塞读。

总结read 函数返回值:

1. 返回非零值:  实际read到的字节数

2. 返回-1:

1):errno != EAGAIN (或!= EWOULDBLOCK)  read出错

2):errno == EAGAIN (或== EWOULDBLOCK)  设置了非阻塞读,并且没有数据到达。

3. 返回0:读到文件末尾

lseek函数

文件偏移

Linux中可使用系统函数lseek来修改文件偏移量(读写位置)

每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。

但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。

lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)。

fseek的作用及常用参数。 SEEK_SET()、SEEK_CUR(当前位置)、SEEK_END(文件尾)

int fseek(FILE *stream, long offset, int whence);  成功返回0;失败返回-1

特别的:超出文件末尾位置返回0(返回0标志着成功,不会出错);往回超出文件头位置,返回-1(失败)

off_t lseek(int fd, off_t offset, int whence); 失败返回-1;成功:返回的值是较文件起始位置向后的偏移量。

特别的:lseek允许超过文件结尾设置偏移量,文件会因此被拓展(必须要有IO操作之后,拓展才会生效)。

  1. lseek(fd, , SEEK_SET);
  2. write(fd, "s", ); // 必须要有IO操作

注意文件“读”和“写”使用同一偏移位置。【lseek.c】

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6.  
  7. int main(void)
  8. {
  9. int fd, n;
  10. char msg[] = "It's a test for lseek\n";
  11. char ch;
  12.  
  13. fd = open("lseek.txt", O_RDWR|O_CREAT, );
  14. if(fd < ){
  15. perror("open lseek.txt error");
  16. exit();
  17. }
  18.  
  19. write(fd, msg, strlen(msg)); //使用fd对打开的文件进行写操作,问价读写位置位于文件结尾处。
  20.  
  21. lseek(fd, , SEEK_SET); //修改文件读写指针位置,位于文件开头。 注释该行会,将读不到数据
  22.  
  23. while((n = read(fd, &ch, ))){
  24. if(n < ){
  25. perror("read error");
  26. exit();
  27. }
  28. write(STDOUT_FILENO, &ch, n); //将文件内容按字节读出,写出到屏幕
  29. }
  30.  
  31. close(fd);
  32.  
  33. return ;
  34. }

lseek常用应用:

1. 使用lseek拓展文件:write操作才能实质性的拓展文件。单lseek是不能进行拓展的。

一般:write(fd, "a", 1);

od -tcx filename  查看文件的16进制表示形式

od -tcd filename  查看文件的10进制表示形式

2. 通过lseek获取文件的大小:lseek(fd, 0, SEEK_END);             【lseek_test.c】

【最后注意】:lseek函数返回的偏移量总是相对于文件头而言

fcntl函数

改变一个【已经打开】的文件的 访问控制属性。

重点掌握两个参数的使用,F_GETFL 和 F_SETFL。【fcntl.c】

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #define MSG_TRY "try again\n"
  9.  
  10. int main(void)
  11. {
  12. char buf[];
  13. int flags, n;
  14.  
  15. flags = fcntl(STDIN_FILENO, F_GETFL); //获取stdin属性信息
  16. if(flags == -){
  17. perror("fcntl error");
  18. exit();
  19. }
  20. flags |= O_NONBLOCK;
  21. int ret = fcntl(STDIN_FILENO, F_SETFL, flags);
  22. if(ret == -){
  23. perror("fcntl error");
  24. exit();
  25. }
  26.  
  27. tryagain:
  28. n = read(STDIN_FILENO, buf, );
  29. if(n < ){
  30. if(errno != EAGAIN){
  31. perror("read /dev/tty");
  32. exit();
  33. }
  34. sleep();
  35. write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
  36. goto tryagain;
  37. }
  38. write(STDOUT_FILENO, buf, n);
  39.  
  40. return ;
  41. }

ioctl函数

对设备的I/O通道进行管理,控制设备特性。(主要应用于设备驱动程序中)。

通常用来获取文件的【物理特性】(该特性,不同文件类型所含有的值各不相同) 【ioctl.c】

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/ioctl.h>
  5.  
  6. int main(void)
  7. {
  8. struct winsize size;
  9.  
  10. if (isatty(STDOUT_FILENO) == ) //
  11. exit();
  12.  
  13. if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)<) {
  14. perror("ioctl TIOCGWINSZ error");
  15. exit();
  16. }
  17. printf("%d rows, %d columns\n", size.ws_row, size.ws_col);
  18.  
  19. return ;
  20. }

传入传出参数

传入参数:

const 关键字修饰的 指针变量  在函数内部读操作。  char *strcpy(cnost char *src, char *dst);

传出参数:

1. 指针做为函数参数

2. 函数调用前,指针指向的空间可以无意义,调用后指针指向的空间有意义,且作为函数的返回值传出

3. 在函数内部写操作。

传入传出参数:

1. 调用前指向的空间有实际意义 2. 调用期间在函数内读、写(改变原值)操作 3.作为函数返回值传出。

扩展阅读:

关于虚拟4G内存的描述和解析:

一个进程用到的虚拟地址是由内存区域表来管理的,实际用不了4G。而用到的内存区域,会通过页表映射到物理内存。

所以每个进程都可以使用同样的虚拟内存地址而不冲突,因为它们的物理地址实际上是不同的。内核用的是3G以上的1G虚拟内存地址,

其中896M是直接映射到物理地址的,128M按需映射896M以上的所谓高位内存。各进程使用的是同一个内核。

首先要分清“可以寻址”和“实际使用”的区别。

其实我们讲的每个进程都有4G虚拟地址空间,讲的都是“可以寻址”4G,意思是虚拟地址的0-3G对于一个进程的用户态和内核态来说是可以访问的,而3-4G是只有进程的内核态可以访问的。并不是说这个进程会用满这些空间。

其次,所谓“独立拥有的虚拟地址”是指对于每一个进程,都可以访问自己的0-4G的虚拟地址。虚拟地址是“虚拟”的,需要转化为“真实”的物理地址。

好比你有你的地址簿,我有我的地址簿。你和我的地址簿都有1、2、3、4页,但是每页里面的实际内容是不一样的,我的地址簿第1页写着3你的地址簿第1页写着4,对于你、我自己来说都是用第1页(虚拟),实际上用的分别是第3、4页(物理),不冲突。

内核用的896M虚拟地址是直接映射的,意思是只要把虚拟地址减去一个偏移量(3G)就等于物理地址。同样,这里指的还是寻址,实际使用前还是要分配内存。而且896M只是个最大值。如果物理内存小,内核能使用(分配)的可用内存也小。

linux系统编程--文件IO的更多相关文章

  1. Linux系统编程--文件IO操作

    Linux思想即,Linux系统下一切皆文件. 一.对文件操作的几个函数 1.打开文件open函数 int open(const char *path, int oflags); int open(c ...

  2. Linux系统编程@终端IO

    Linux系统中终端设备种类  终端是一种字符型设备,有多种类型,通常使用tty 来简称各种类型的终端设备.终端特殊设备文件一般有以下几种: 串行端口终端(/dev/ttySn ) ,伪终端(/dev ...

  3. Linux系统编程@文件操作(一)

    只总结了部分常用的内容,详细内容参考<UNIX环境高级编程>及相关书籍. Linux中文件编程可以使用两种方法 Linux系统调用(依赖于系统) C语言库函数(不依赖于系统) Linux系 ...

  4. 系统编程--文件IO

    1.文件描述符 文件描述符是一个非负整数,当打开一个现有文件或创建一个新文件时候,内核向进程返回一个文件描述符,新打开文件返回文件描述符表中未使用的最小文件描述符.Unix系统shell使用文件描述符 ...

  5. linux系统编程:IO读写过程的原子性操作实验

    所谓原子性操作指的是:内核保证某系统调用中的所有步骤(操作)作为独立操作而一次性加以执行,其间不会被其他进程或线程所中断. 举个通俗点的例子:你和女朋友OOXX的时候,突然来了个电话,势必会打断你们高 ...

  6. Linux系统编程--文件描述符的复制dup()和dup2()【转】

    本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...

  7. Linux系统编程---文件I/O(open、read、write、lseek、close)

    文件描述符 定义:对内核而言,文件描述符相当于一个文件的标识,它是一个非负整数,当打开(open)一个现有文件或者创建(creat)一个新文件时,内核会向进程返回一个文件描述符 在unix中(文件描述 ...

  8. linux系统编程之文件与io(一)

    经过了漫长的学习,C语言相关的的基础知识算是告一段落了,这也是尝试用写博客的形式来学习c语言,回过头来看,虽说可能写的内容有些比较简单,但是个人感觉是有史起来学习最踏实的一次,因为里面的每个实验都是自 ...

  9. linux系统编程之文件与io(五)

    上一节中已经学习了文件描述符的复制,复制方法有三种,其中最后一种fcntl还并未使用到,关于这个函数,不光只有复制文件描述符的功能,还有其它一些用法,本节就对其进行一一剖析: fcntl常用操作: 这 ...

随机推荐

  1. IPv4

    1.IPv4分类地址 PC0(192.168.0.1) 和PC1(172.168.0.1)如果要ping通的话需要设置各自网关 PC0  设置IP  和  默认网关=路由器设置IP 2.Gigabit ...

  2. 2.5路由网关:Zuul

    在原有的工程上,创建一个新的工程 创建service-zuul工程 其pom.xml文件如下: <?xml version="1.0" encoding="UTF- ...

  3. 适合新手的160个creakme(三)

    先跑一下,这个程序应该是有定时器,多久之后自动开启,测试一下输入,序列号以字母方式输入会出现类型不匹配,之后程序自动退出 但是如果以数字方式输入序列号,则会出现,Try Again,所以这里序列号应该 ...

  4. OBB碰撞

    OBB碰撞检测,坐标点逆时针 class OBBTest extends egret.DisplayObjectContainer { private obb1:OBB; private obb2:O ...

  5. DaemonSet和StatefulSet

    DaemonSet 的使用 通过该控制器的名称我们可以看出它的用法:Daemon,就是用来部署守护进程的,DaemonSet用于在每个Kubernetes节点中将守护进程的副本作为后台进程运行,说白了 ...

  6. js摄像头

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  7. android-studio-ide 安装到运行第一个helloword,坑记录

    1: 安装是提示  机器虚拟化问题,系统如开启了Hyper-V,必须关闭服务 2:安装完后,建立第一个项目,gradle build 一直转圈,最后报错 Gradle project sync fai ...

  8. 【温故知新】php 魔术方法

    <?php class Magic{ private $name; /** *构造方法,在类被实例化时自动调用,一般用于初始化操作 */ public function __construct( ...

  9. 安卓开发之sql语句增删改查2(利用谷歌封装好的API进行增删改查)

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  10. echarts和v-chart使用心得

    echarts的响应式 每次窗口大小改变的时候都会触发onresize事件,这个时候我们将echarts对象的尺寸赋值给窗口的大小这个属性,从而实现图表对象与窗口对象的尺寸一致的情况window.on ...