网页设计与制作简答题,南宁网站建设seo优化营销制作,公司网站年费,域名访问网站 过程netstat netstat 是一个用来查看网络状态的重要工具. 语法#xff1a;netstat [选项] 功能#xff1a;查看网络状态 常用选项#xff1a; • n 拒绝显示别名#xff0c;能显示数字的全部转化成数字 • l 仅列出有在 Listen (监听) 的服務状态 • p 显示建立相关链接的程序…netstatnetstat是一个用来查看网络状态的重要工具.语法netstat [选项]功能查看网络状态常用选项•n拒绝显示别名能显示数字的全部转化成数字•l仅列出有在Listen (监听)的服務状态•p显示建立相关链接的程序名•t (tcp)仅显示tcp相关选项•u (udp)仅显示udp相关选项•a (all)显示所有选项默认不显示LISTEN相关pidof在查看服务器的进程id时非常方便.语法pidof [进程名]功能通过进程名,查看进程idTCP抓包sudo tcpdump -i any tcp注意-i any指定捕获所有网络接口上的数据包tcp指定捕获TCP协议的数据包。i可以理解成为interface的意思如果你只想捕获某个特定网络接口如eth0上的TCP报文可以使用以下命令sudo tcpdump -i eth0 tcp使用host关键字可以指定源或目的IP地址。例如要捕获源IP地址为192.168.1.100的TCP报文可以使用以下命令$ sudo tcpdump src host 192.168.1.100 and tcp同时指定源和目的IP地址可以使用and关键字连接两个条件sudo tcpdump src host 192.168.1.100 and dst host 192.168.1.200 and tcp捕获特定端口的TCP报文使用port关键字可以指定端口号。例如要捕获端口号为80的TCP报文通常是 HTTP 请求可以使用以下命令sudo tcpdump port 80 and tcp保存捕获的数据包到文件使用-w选项可以将捕获的数据包保存到文件中以便后续分析。sudo tcpdump -i eth0 port 80 -w data.pcap这将把捕获到的HTTP流量保存到名为data.pcap的文件中。•了解pcap后缀的文件通常与PCAPPacket Capture文件格式相关这是一种用于捕获网络数据包的文件格式从文件中读取数据包进行分析使用-r选项可以从文件中读取数据包进行分析tcpdump -r data.pcap这将读取 data.pcap 文件中的数据包并进行分析。注意事项• 使用 tcpdump 时请确保你有足够的权限来捕获网络接口上的数据包。通常你需要以 root 用户身份运行 tcpdump。• 使用 tcpdump 的时候有些主机名会被云服务器解释成为随机的主机名如果不想要就用-n 选项• 主机观察三次握手的第三次握手不占序号自旋锁1. 概述自旋锁是一种多线程同步机制用于保护共享资源。线程获取锁失败时会 ** 循环自旋不断检查锁状态** 而非进入休眠以此减少线程切换开销适用于短时间锁竞争但不合理使用会造成 CPU 资源浪费。2. 原理用共享标志位表示锁状态true表示锁被占用false表示锁可用。线程尝试获取锁时若标志位为false则将其设为true占用锁并进入临界区。若标志位为true则在循环中持续自旋等待直到锁被释放。3. 优缺点优点低延迟避免线程休眠与唤醒提升锁操作效率。减少系统调度开销等待线程不阻塞无需上下文切换。缺点CPU 资源浪费锁持有时间较长时自旋线程会持续占用 CPU。可能引发活锁多线程同时自旋且无退避策略时可能都无法获取锁。4. 使用场景锁占用时间极短的场景如多线程对共享数据进行简单读写。系统底层用于同步多个 CPU 对共享资源的访问。5. 实现原理依赖原子操作如 CAS 指令保证锁状态修改的原子性避免并发冲突注意事项锁持有时间要短使用自旋锁时必须确保锁被释放的时间尽可能短否则等待线程会持续自旋造成大量 CPU 资源浪费。多 CPU 环境下的效率问题在多 CPU 环境中自旋锁可能不如其他锁机制高效因为等待线程可能在不同的 CPU 核心上持续自旋等待无法释放计算资源。结论自旋锁是一种适用于短时间锁竞争的同步机制它通过避免线程休眠和上下文切换显著降低了锁操作的开销提升了效率。但它也存在明显缺点长时间持有锁会导致 CPU 资源浪费且在无退避策略的1.pthread_spin_init()—— 初始化自旋锁int pthread_spin_init(pthread_spinlock_t *lock, int pshared);项说明功能初始化一个自旋锁必须在使用前调用参数 1lock输入输出参数指向pthread_spinlock_t变量的指针用于存储初始化后的锁状态参数 2pshared输入参数锁的共享范围-PTHREAD_PROCESS_PRIVATE仅当前进程内线程共享最常用-PTHREAD_PROCESS_SHARED可跨进程共享需配合共享内存返回值成功返回0失败返回非 0 错误码如EINVAL、ENOMEM注意未初始化的锁不能使用同一锁不能重复初始化2.pthread_spin_destroy()—— 销毁自旋锁int pthread_spin_destroy(pthread_spinlock_t *lock);项说明功能销毁已初始化的自旋锁释放资源参数lock输入输出参数指向要销毁的pthread_spinlock_t变量的指针返回值成功返回0失败返回非 0 错误码如EINVAL表示锁无效注意不能销毁正在被其他线程持有的锁销毁后不能再使用该锁除非重新初始化3.pthread_spin_lock()—— 阻塞式加锁int pthread_spin_lock(pthread_spinlock_t *lock);项说明功能阻塞式获取锁获取不到则持续自旋等待直到锁可用参数lock输入输出参数指向要获取的自旋锁指针返回值成功返回0失败返回非 0 错误码如EDEADLK检测到死锁注意自旋锁不支持重入同一线程多次加锁会导致死锁持有锁的时间必须极短4.pthread_spin_trylock()—— 非阻塞式尝试加锁int pthread_spin_trylock(pthread_spinlock_t *lock);项说明功能非阻塞式尝试加锁获取不到则立即返回不会自旋等待参数lock输入输出参数指向要尝试获取的自旋锁指针返回值- 成功获取锁返回0- 锁被占用返回EBUSY- 其他错误返回非 0 错误码注意适合 “不想等待失败则做其他事” 的场景同样不支持重入5.pthread_spin_unlock()—— 解锁int pthread_spin_unlock(pthread_spinlock_t *lock);项说明功能释放自旋锁必须由持有锁的线程调用参数lock输入输出参数指向要释放的自旋锁指针返回值成功返回0失败返回非 0 错误码如EPERM表示调用线程不持有该锁注意未持有锁的线程调用解锁会导致未定义行为如程序崩溃#include stdio.h #include stdlib.h #include string.h #include unistd.h #include pthread.h int ticket 20; // 1. 取消自旋锁变量注释 pthread_spinlock_t lock; void *route(void *arg) { char *id (char *)arg; while (1) { // 2. 加锁获取自旋锁保护临界区 pthread_spin_lock(lock); if (ticket 0) { usleep(1000); // 模拟售票耗时短时间符合自旋锁使用原则 printf(%s sells ticket:%d\n, id, ticket); ticket--; // 3. 解锁释放自旋锁 pthread_spin_unlock(lock); } else { // 4. 无票时也要解锁避免死锁 pthread_spin_unlock(lock); break; } } // 5. C语言中用NULL而非nullptr return NULL; } int main(void) { // 6. 初始化自旋锁 pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE); pthread_t t1, t2, t3; // 创建3个售票线程 pthread_create(t1, NULL, route, (void *)thread 1); pthread_create(t2, NULL, route, (void *)thread 2); pthread_create(t3, NULL, route, (void *)thread 3); // 7. 等待所有子线程执行完成核心修复点 pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_join(t3, NULL); // 8. 销毁自旋锁释放资源 pthread_spin_destroy(lock); return 0; }读写锁在编写多线程的时候有一种情况是十分常见的。那就是有些公共数据修改的机会比较少。相比较改写它们读的机会反而高的多。通常而言在读的过程中往往伴随着查找的操作中间耗时很长。给这种代码段加锁会极大地降低我们程序的效率。那么有没有一种方法可以专门处理这种多读少写的情况呢有那就是读写锁。1.pthread_rwlockattr_setkind_np()—— 设置读写锁优先级int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref);项说明功能设置读写锁的优先级策略读者优先 / 写者优先属于非标准扩展_np表示 non-portable。参数attr输入参数指向pthread_rwlockattr_t类型的属性对象指针用于存储优先级设置。参数pref输入参数优先级选项共 3 种-PTHREAD_RWLOCK_PREFER_READER_NP默认读者优先可能导致写者饥饿-PTHREAD_RWLOCK_PREFER_WRITER_NP写者优先存在 BUG实际表现与读者优先一致-PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP写者优先且写者不能递归加锁返回值成功返回0失败返回非 0 错误码如EINVAL表示参数无效。注意该接口为非标准扩展不同系统实现可能存在差异优先级策略会影响读写锁的竞争行为需谨慎选择。2.pthread_rwlock_init()—— 初始化读写锁c运行int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);项说明功能初始化读写锁必须在使用前调用。参数rwlock输入输出参数指向pthread_rwlock_t类型的读写锁指针用于存储初始化后的锁状态。参数attr输入参数指向读写锁属性对象的指针若为NULL则使用默认属性读者优先。返回值成功返回0失败返回非 0 错误码如ENOMEM表示内存不足。注意未初始化的读写锁不能使用同一锁不能重复初始化。3.pthread_rwlock_destroy()—— 销毁读写锁int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);项说明功能销毁已初始化的读写锁释放系统资源。参数rwlock输入输出参数指向要销毁的pthread_rwlock_t类型的读写锁指针。返回值成功返回0失败返回非 0 错误码如EBUSY表示锁仍被线程持有。注意不能销毁正在被其他线程持有的锁销毁后不能再使用该锁除非重新初始化。4.pthread_rwlock_rdlock()—— 获取读锁共享锁int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);项说明功能获取读锁共享锁多个线程可同时持有读锁写锁会被阻塞。参数rwlock输入输出参数指向要获取读锁的pthread_rwlock_t类型的读写锁指针。返回值成功返回0失败返回非 0 错误码如EDEADLK检测到死锁。注意读锁是共享的适合读多写少的场景持有读锁时不能再获取写锁否则会导致死锁。5.pthread_rwlock_wrlock()—— 获取写锁独占锁int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);项说明功能获取写锁独占锁写锁持有期间所有读锁和写锁请求都会被阻塞。参数rwlock输入输出参数指向要获取写锁的pthread_rwlock_t类型的读写锁指针。返回值成功返回0失败返回非 0 错误码如EDEADLK检测到死锁。注意写锁是独占的持有写锁时不能再获取读锁或写锁否则会导致死锁写锁持有时间应尽量短。6.pthread_rwlock_unlock()—— 释放读写锁int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);项说明功能释放读锁或写锁必须由持有锁的线程调用。参数rwlock输入输出参数指向要解锁的pthread_rwlock_t类型的读写锁指针。返回值成功返回0失败返回非 0 错误码如EPERM表示调用线程不持有该锁。注意未持有锁的线程调用解锁会导致未定义行为如程序崩溃解锁后其他线程可竞争获取锁。#include iostream #include pthread.h #include unistd.h #include vector #include cstdlib #include ctime // 共享资源 int shared_data 0; // 读写锁 pthread_rwlock_t rwlock; // 读者线程函数 void *Reader(void *arg) { //sleep(1); //读者优先一旦读者进入读者很多写者基本就很难进入了 int number *(int *)arg; while (true) { pthread_rwlock_rdlock(rwlock); // 读者加锁 std::cout 读者- number 正在读取数据数据是: shared_data std::endl; sleep(1); // 模拟读取操作 pthread_rwlock_unlock(rwlock); // 解锁 } delete (int*)arg; return NULL; } // 写者线程函数 void *Writer(void *arg) { int number *(int *)arg; while (true) { pthread_rwlock_wrlock(rwlock); // 写者加锁 shared_data rand() % 100; // 修改共享数据 std::cout 写者- number 正在写入。新的数据是: shared_data std::endl; sleep(2); // 模拟写入操作 pthread_rwlock_unlock(rwlock); // 解锁 } delete (int*)arg; return NULL; } int main() { srand(time(nullptr)^getpid()); pthread_rwlock_init(rwlock, NULL); // 初始化读写锁 // 可以更高读写数量配比观察现象 const int reader_num 2; const int writer_num 2; const int total reader_num writer_num; pthread_t threads[total]; // 假设读者和写者数量相等 // 创建读者线程 for (int i 0; i reader_num; i) { int *id new int(i); pthread_create(threads[i], NULL, Reader, id); } // 创建写者线程 for (int i reader_num; i total; i) { int *id new int(i - reader_num); pthread_create(threads[i], NULL, Writer, id); } // 等待所有线程完成 for (int i 0; i total; i) { pthread_join(threads[i], NULL); } pthread_rwlock_destroy(rwlock); // 销毁读写锁 return 0; }读者优先Reader-Preference在这种策略中系统会尽可能多地允许多个读者同时访问资源比如共享文件或数据而不会优先考虑写者。这意味着当有读者正在读取时新到达的读者会立即被允许进入读取区而写者则会被阻塞直到所有读者都离开读取区。读者优先策略可能会导致写者饥饿即写者长时间无法获得写入权限特别是当读者频繁到达时。写者优先Writer-Preference在这种策略中系统会优先考虑写者。当写者请求写入权限时系统会尽快地让写者进入写入区即使此时有读者正在读取。这通常意味着一旦有写者到达所有后续的读者都会被阻塞直到写者完成写入并离开写入区。写者优先策略可以减少写者等待的时间但可能会导致读者饥饿即读者长时间无法获得读取权限特别是当写者频繁到达时。