
linux系统编程
文章平均质量分 60
modi000
生命不止,奋斗不息!
展开
-
通过多线程并发方式实现服务器
【代码】通过多线程并发方式(fork)实现服务器。原创 2024-02-29 00:15:20 · 735 阅读 · 0 评论 -
Linux之循环创建多个子进程
但是shell进程不知道还有子进程,当父进程执行完(打印了 I am parent),shell进程抢占了前台,恢复到正常状态,此时子进程3用了终端,所以这句话( I am 3 child, pid = 19810)就没打印到下一行的行首,而是直接打印到光标的后面的位置上,打印完之后,做了个换行,光标移到下一行起始位置,这时候子进程2又抢占了终端,在光标之后打印了一句话……当我去掉所有的sleep函数之后,父进程和子进程以及shell进程之间共同抢夺CPU,shell进程并不知道父进程又创建了子进程。转载 2024-02-29 00:02:47 · 185 阅读 · 0 评论 -
通过多进程并发方式(fork)实现服务器(注意要回收子进程)
2、子进程完成数据交互后,close(cfd);此时成为僵尸进程,所以需要在父进程中收尸,回收进程描述符等资源。但此时父进程在accept,无法waitpid(),此时使用signal的方式SIGCHILD来解决收尸问题,当子进程成僵尸进程后,由内核自动回收。调用fork()创建子进程后,子进程继承cfd,lfd,通过该cfd与连接过来的客户端通信,lfd对子进程来说没用,可以直接close(lfd);对于父进程来说,只是用来建立连接的,故父进程中的cfd没有用,直接close(cfd);原创 2024-02-28 23:52:08 · 624 阅读 · 0 评论 -
gcc联合编译
Wall 参数:打开gcc所有警告。原创 2024-02-25 23:21:10 · 355 阅读 · 0 评论 -
GDB调试
虽然它是命令行模式的调试工具,但是它的功能强大到你无法想象,能够让用户在程序运行时观察程序的内部结构和内存的使用情况。要调试C/C++的程序,首先在编译时,要使用gdb调试程序,在使用gcc编译源代码时必须加上“-g”参数。GDB中的命令很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。说明没有带有调试功能,则不能被调试。/home/minger/share/tencent/gdb/main是程序的路径。1、按照自定义的方式启动运行需要调试的程序。3、程序暂停时的值的监视。转载 2023-11-05 14:26:50 · 96 阅读 · 0 评论 -
长连接 、短连接、心跳机制
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。很多网络设备,尤其是NAT路由器,由于其硬件的限制(例如内存、CPU处理能力),无法保持其上的所有连接,因此在必要的时候,会在连接池中选择一些不活跃的连接踢掉。转载 2023-10-31 11:35:46 · 383 阅读 · 0 评论 -
互斥信号量和二进制信号量的区别
打印机资源只有一个,abc三个任务共享,当a取得使用权后,为了防止其他任务错误地释放了信号量(),必须将打印机房的门关起来(进入临界段),用完后,释放信号量,再把门打开(出临界段),其他任务再进去打印。因此,为了访问共享资源,线程必须从信号量得到通行证, 如果该信号量的计数大于0,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。当信号量被释放一个,值被加一后,系统自动从等待队列中唤醒一个等待中的线程,让其获得信号量,同时信号量再减一。同一个任务可以递归申请。转载 2023-10-18 13:29:28 · 306 阅读 · 0 评论 -
PV操作说明
进程间的关系主要指是进程同步还是进程互斥,它决定了PV操作在进程中的意义,进程的互斥往往是进程间的顺序推进,而进程的同步是多个进程间的协同工作,具有并发性。(2)用PV原语实现进程的同步。利用PV原语实现进程同步的方法是:首先判断进程间的关系为同步的,且为各并发进程设置私有信号量,然后为私有信号量赋初值,最后利用PV原语和私有信号量规定各进程的执行顺序。当遇到进程同步问题时,虽然也成对出现,但P操作应在等待消息的进程中,V操作应在发送消息的进程中,只有在含有V操作的进程发送消息之后,P操作的进程才能执行。转载 2023-08-25 15:54:31 · 3968 阅读 · 0 评论 -
获取线程id的方法
参考该文。 我们发现,调用syscall获取的id与ps命令获取的相同。pthread_self 是posix描述的线程ID(并非内核真正的线程id),相对于进程中各个线程之间的标识号,对于这个进程内是唯一的,而不同进程中,每个线程的 pthread_self() 可能返回是一样的。所以,获取线程真正的id方法:............原创 2022-06-09 10:24:12 · 2811 阅读 · 0 评论 -
pthread_cancel pthread_testcancel测试
pthread_cancel用于取消一个线程,但被取消的线程要有取消点,才能被取消。pthread_testcancel用于设置取消点运行结果:转载 2022-06-08 16:17:30 · 269 阅读 · 0 评论 -
(转)Linux 多线程编程---pthread_testcancel()等讲解
1. 所谓线程就是“一个进程内部的一个控制序列”。也就是一个进程内部的并行的基础!2. Linux进程可以看成只有一个控制线程: 一个进程在同一时刻只做一件事情。有了多个控制线程以后, 在程序设计时可以把进程设计成在同一时刻能够做不止一件事, 每个线程处理各只独立的任务。即所谓并行! 3. 线程的优点: (1)通过为每种事件类型的处理分配单独的线程,能够简化处理异步时间的代码。 (2)多个线程可以自动转载 2022-06-08 16:14:32 · 2001 阅读 · 0 评论 -
创建线程的心得
当编写程序的时候,一个分支是个死循环时,为了不耽误接下来的代码顺序执行,此时就可以起一个线程,用来单独执行死循环程序。qq原创 2022-06-07 13:15:11 · 491 阅读 · 0 评论 -
消息队列用于线程间通信
我们知道,消息队列是进程间通信的方法之一,当然,消息队列也可以用于线程间通信。进程间通信的时候,我们需要使用ftok()函数创建同一个key值,线程间通信时,我们可以原创 2021-06-14 23:03:59 · 2833 阅读 · 0 评论 -
在子线程中创建子线程及线程查看方法
小结:我们看到,son线程的退出,并没有影响到孙线程的运行,因为进程并未退出。 以上述方式一的形式查看线程:1)同一进程中的线程是平等的,没有父子之分。当然也包括所谓的主线程、在主线程中创建的线程、在所谓的子线程中创建的线程。线程既然是平等的,只要进程不退出,倘若son线程退出,我们看到不会影响到孙线程的运行。2)孙线程在子线程中创建,可以理解为,启动孙线程的顺序点是在此时,而并非在主线程中。也就是说,我们可以在任意我们需要创建一个平行任务的地方,创建一个子线程,而并非得在主线程中创建。3)线程函数,其实,原创 2022-06-02 09:44:39 · 2875 阅读 · 1 评论 -
Linux 线程调度与优先级
【转】Linux下线程学习笔记(一)-frankzfz-ChinaUnix博客Linux下线程的调度策略与优先级(一)-frankzfz-ChinaUnix博客Linux内核的三种调度策略: 1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃 3,SCHED_RR实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的R转载 2022-06-01 09:30:02 · 3372 阅读 · 0 评论 -
判断文件或文件夹是否存在的方法
判断文件是否存在 fopen的读,参考该文。判断文件夹是否存在 access函数,参考该文access函数还能文件是否存在,以及判断文件(夹)的属性原创 2022-05-31 15:49:35 · 704 阅读 · 0 评论 -
Linux access函数讲解
函数:#include<unistd.h>int access(const char* pathname, int mode);参数介绍: pathname 是文件的路径名+文件名 mode:指定access的作用,取值如下F_OK 值为0,判断文件是否存在X_OK 值为1,判断对文件是可执行权限W_OK 值为2,判断对文件是否有写权限R_OK 值为4,判断对文件是否有读权限注:后三种可以使用或“|”的方式,一起使用,如W_OK|R_...转载 2022-05-31 15:46:08 · 8009 阅读 · 0 评论 -
使用fopen函数读属性判断文件是否存在
int func(char *pName){ FILE *fp; fp = fopen( pName, "r" ); if( fp != NULL ) { fclose( fp ); return 1; } return 0;}利用fopen的 可读属性判断文件是否存在。注意:fopen以读的形式打开文件,只有当文件不存在时,返回值才为空如果文件的没有可读属性,只要文件存在,也是可以被打开,并读出其内容的。.原创 2022-05-31 10:27:12 · 2744 阅读 · 0 评论 -
man posix_spawn
以下是在ubuntu上看到的,凝思系统上该函数能用,找不到man配置。POSIX_SPAWN(3) Linux Programmer's Manual POSIX_SPAWN(3)NAME posix_spawn, posix_spawnp - spawn a processSYNOPSIS ...原创 2022-05-31 10:02:06 · 718 阅读 · 0 评论 -
使用SIGCHLD信号捕捉子进程状态
如题,使用SIGCHLD信号,为子进程收尸,同时捕捉子进程的退出的状态;实现效果:1)回收子进程资源;2)进程重启(当发现子进程退出后,重启该进程)int ret,g_pid;extern char **environ;char* process_name;main(){ if (signal(SIGCHLD, child_end) == SIG_ERR ) { printf("can't signal(SIGCHLD, child_end)原创 2022-05-31 09:33:11 · 430 阅读 · 0 评论 -
TZ环境变量,时区
如上例所示,代码段 setenv( "TZ", "CST-08", 1 );//设置东八区 北京时间 tzset();// 这条代码执行的意思是什么?待解决。转载:TZ环境变量,时区,夏令时_pirate_sir的博客-优快云博客_tz环境变量#include <stdio.h>#include <sys/time.h>#include <stdlib.h>#include <unistd.h> /**...原创 2022-05-30 16:30:51 · 3584 阅读 · 0 评论 -
#pragma pack() 易忽略的问题
#pragma pack() 易忽略的问题 C/C++中,class、struct、union默认的大小对齐方式为按照成员变量所占空间最大的大小进行对齐,如:typedef struct test{ char a; int b; double c;}test_t;则test结构体内所有成员变量按照double类型进行字节对齐,此时sizeof(test_t)等于8*3。在网络通信中,为了让数据包更紧凑些,我们往往希望能够通过#pragma pack预编译命令改变默转载 2022-05-30 14:28:02 · 762 阅读 · 0 评论 -
linux系统有线程描述符吗,linux--fork后父子线程共享文件描述符的理解
本篇文章主要总结下共享文件描述符,系统文件表,内存中索引结点表这几个概念。fork进程后,父子进程共享文件描述符这点其实很不好理解,同时也很重要,在管道,信号等应用中都可能会设计到,通过查阅网上的资料,整理如下概念介绍在C程序中,文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述转载 2022-05-30 12:23:07 · 358 阅读 · 0 评论 -
【Linux 进程】fork父子进程间共享数据分析
之前我们通过fork()函数,得知了父子进程之间的存在着代码的拷贝,且父子进程都相互独立执行,那么父子进程是否共享同一段数据,即是否存在着数据共享。接下来我们就来分析分析父子进程是否存在着数据共享。我们都知道,在linux下,内存存储的位置是全局变量,栈区,堆区,以及文件。字符常量区我们这里不作分析。下面我们依次以实际代码来验证它们是否存在着数据共享。所谓的父子进程数据共享,通俗点说就是父进程或者子进程对于数据的更改,会使得子进程或者父进程的数据同步更改。代码检测的思想是让父子进程中的一个修改数据,未对转载 2022-05-30 11:13:09 · 3896 阅读 · 0 评论 -
理解mmap()
mmap, 从函数名就可以看出来这是memory map, 即地址的映射, 是一种内存映射文件的方法, (其他的还有mmap()系统调用,Posix共享内存,以及系统V共享内存,这些我们有机会在后续的文章讨论,今天的男主角是mmap),将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),w转载 2022-05-30 10:48:05 · 372 阅读 · 0 评论 -
SystemV 和Posix两种方式实现共享内存
正如实现信号量的方式有SystemV 和Posix两种形式,实现共享内存也有SystemV 和Posix两种形式,参考该文和该文和该文一、Posix形式:(常用)i用到如下函数:shm_openmmapftruncateshm_unlink二、System V 形式:参考该文。#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sy.原创 2022-05-30 09:45:41 · 564 阅读 · 0 评论 -
linux 内存文件共享,两种Linux共享内存的比较
现代Linux有两种共享内存机制:POSIX共享内存(shm_open()、shm_unlink())System V共享内存(shmget()、shmat()、shmdt())其中,System V共享内存历史悠久,一般的UNIX系统上都有这套机制;而POSIX共享内存机制接口更加方便易使用,一般是结合内存映射mmap用。mmap和System V共享内存的主要区别在于:sysv shm是持久化的,除非被一个进程明确的删除,否则它始终存在于内存里,直到系统关机;mmap映射的内存在不是持久转载 2022-05-30 09:19:12 · 1902 阅读 · 0 评论 -
mmap映射区和shm共享内存的区别总结
linux中的两种共享内存。一种是我们的IPC通信System V版本的共享内存,另外的一种就是我们今天提到的存储映射I/O(mmap函数)在说mmap之前我们先说一下普通的读写文件的原理,进程调用read或是write后会陷入内核,因为这两个函数都是系统调用,进入系统调用后,内核开始读写文件,假设内核在读取文件,内核首先把文件读入自己的内核空间,读完之后进程在内核回归用户态,内核把读入内核内存的数据再copy进入进程的用户态内存空间。实际上我们同一份文件内容相当于读了两次,先读入内核空间,再从内核空间转载 2022-05-30 08:52:01 · 715 阅读 · 0 评论 -
子线程先于主线程退出
参考该文,该文中已经列举了多种方法,实际中还可以如下操作:例如:当进程中有多个子线程,子线程中还有子线程。可以设计如下:进程中可以只对一个死循环的子线程中使用phtread_join操作,从而保证进程不退出。进程中的其他线程可以都使用 pthread_detach(pthread_self());(无论是进程中的,还是线程中的子线程),保证线程结束后,资源能够回收。...原创 2022-05-24 09:25:44 · 528 阅读 · 0 评论 -
线程和进程同步及进程间通信总结
一、线程(或进程)同步的理解互斥:两个线程(进程)不能同时访问同一资源,访问资源的顺序不确定。同步:两个线程(进程)具有一定的先后顺序来访问同一资源。(互斥的同时,线程(进程)需按照先后顺序访问资源。)比如:生产者和消费者,必须是现生产了才能消费;消费了才能有空地,继续生产。二、线程同步机制1、互斥锁1)如果一个线程加了锁,正在访问共享资源,失去了cpu,此时另一个线程没加锁,也是能访问共享资源的。这样就造成了混乱。解决方法:访问共享资源的线程都要加锁。2)pthread_t原创 2022-05-21 10:11:26 · 1717 阅读 · 0 评论 -
最全面的linux信号量解析
信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。二.信号量的分类在学习信号量之前,我们必须先知道——Linux提供两种信号量:(1) 内核信号量,由内核控制路径使用(2) 用户态进程使用的信号量,这种信号量又分为POSIX信号量和SYSTEMV信号量。POSIX信号量又分为有名信号量和无名信号量。有名信号量转载 2022-05-19 10:57:07 · 3818 阅读 · 0 评论 -
进程间通信-信号量
#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);Link with -pthread. sem_init() initializes the unnamed semaphore at the address pointed to by sem. The value argument specifies the initial value for t.原创 2022-05-19 00:00:29 · 150 阅读 · 0 评论 -
信号量函数(semget、semop、semctl)
二.System V信号量和Posix信号量区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量。它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线。例如,应该是semget()而不是sem_get()。然而,所有的的POSIX信号量函数都有一个下划线。下面列出了它们提供的所有函数清单: Systm VPOSIXsemctl()sem_getval...转载 2022-05-18 22:16:52 · 1047 阅读 · 0 评论 -
信号量详细解说
1、信号量概述进化版的互斥锁(1 --> N)由于互斥锁的粒度比较大,如果我们希望在多个线程间对某一对象的部分数据进行共享,使用互斥锁是没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的目的,却无形中导致线程的并发性下降。线程从并行执行,变成了串行执行。与直接使用单进程无异。信号量,是相对折中的一种处理方式,既能保证同步,数据不混乱,又能提高线程并发。2、主要应用函数:sem_init() 函数 功能:初始化一个信号...转载 2022-05-18 21:52:40 · 1377 阅读 · 0 评论 -
pv操作的经典习题
1、有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。semaphore empty = 100;// 记录空座位semaphore mutex = 1;// 作为互斥的访问登记和注销操作void reader(){ while(true) { wait(empty); wait(mutex); ...转载 2022-05-18 19:25:19 · 4350 阅读 · 1 评论 -
操作系统——信号量(理解什么是信号量,信号量如何解决同步互斥问题,信号量一些注意点)
信号量是什么 信号量(semaphore)是操作系统用来解决并发中的互斥和同步问题的一种方法。 信号量是一个与队列有关的整型变量,你可以把它想象成一个数后面拖着一条排队的队列,如图: 那信号量上面值n代表什么意思呢? n>0:当前有可用资源,可用资源数量为n n=0:资源...转载 2022-05-18 15:12:54 · 4886 阅读 · 1 评论 -
进程间通信-消息队列总结
1、消息队列的创建与销毁原则:谁打开,谁关闭;谁创建,谁释放。被动端,进行消息队列的创建和销毁msqid = msgget( key, 0600|IPC_CREAT ) ;//创建flag = msgctl( msqid, IPC_RMID,NULL) ;//销毁主动端,无需创建和销毁。2、命令删除消息队列我们在做测试时,被动端是while死循环,不断的接收消息,while外才会销毁消息,(正常情况下,应该放在信号处理函数中)当我们ctlr+c结束该循环时,则导致并未执行原创 2022-05-18 12:28:01 · 412 阅读 · 0 评论 -
消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例
消息队列函数由msgget、msgctl、msgsnd、msgrcv四个函数组成。下面的表格列出了这四个函数的函数原型及其具体说明。1. msgget函数原型 msgget(得到消息队列标识符或创建一个消息队列对象)所需头文件#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>...转载 2022-05-16 15:40:28 · 3875 阅读 · 0 评论 -
Linux应用编程 | exec函数族
fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。将当前进程的.text、.data替换为所要加载的程序的.text、.data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳。所谓exec函数族,其实有六种以exec开头的函数转载 2022-05-16 10:03:54 · 670 阅读 · 0 评论 -
wait如何处理多进程(多个子进程)
#include <stdio.h>#include <stdlib.h>#include <unistd.h>/* linux 系统调用 wait() * 当用fork()创建子进程,子进程在退出后父进程没有调用wait * 就会产生僵尸进程. * * 下面是用fork循环创建多个子进程,在父进程里调用一次wait * 只能回收一个子进程. * * 下面展示如何用wait()回收多个子进程. * * */int main(void){ .转载 2022-05-14 01:45:05 · 824 阅读 · 0 评论