linux系统编程
文章平均质量分 65
alliiin
寄一个春天
展开
-
自旋锁和读写锁
何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,“自旋”一词就是因此而得名。原创 2023-10-21 14:59:56 · 180 阅读 · 0 评论 -
linux系统编程—线程—互斥锁与条件变量
如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。pthread_mutex_init和pthread_mutex_destroy参数一和通过pthread_mutex_t创建,参数需要的是一个指针。pthread_cond_wait参数一:等待的条件变量(由pthread_cond_t 创建)原创 2023-06-13 18:38:45 · 1410 阅读 · 1 评论 -
linux系统编程—线程的相关概念、创建、等待和退出
在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;操作系统创建线程时,线程处于创建态,CPU调度线程时,线程处于运行态,此时其它已创建的或者时间片到的线程就处于就绪态,当然还有些线程在进行磁盘、网络等IO时就处于阻塞态,操作系统销毁线程时,线程就处于终止态。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。原创 2023-06-11 16:10:18 · 173 阅读 · 2 评论 -
linux系统编程—信号量
简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。nsops:进行操作信号量的个数,即sops结构变量的个数,需大于或等于1。最简单的信号量是一个只有0与1两个值的变量,二值信号量。注:原子操作:单指令的操作称为原子的,单条指令的执行是不会被打断的。原创 2023-06-10 19:10:32 · 237 阅读 · 0 评论 -
linux系统编程—信号
系统默认动作:对该信号的处理保留系统的默认值,对大部分的信号的缺省操作是使得进程终止。typedef void (*sighandler_t)(int)为信号的自定义处理函数:参数列表仅有一个int类型,表示接收的信号。忽略信号:忽略某个信号,对该信号不做任何处理,就象未发生过一样(sigkill和sigstop不能被忽略)。捕捉信号:类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。pid = 0: 发送信号给与调用kill函数进程属于同一进程组的所有进程。原创 2023-06-09 10:15:32 · 102 阅读 · 0 评论 -
linux系统编程—命名管道FIFO
FIFO (First in, First out)不同于匿名管道pipe之处在于它提供一个路径名与之关联,以FIFO的文件形式存储于文件系统中,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。当一个进程以读(r)的方式打开该文件,而另一个进程以写(w)的方式打开该文件,那么内核就会在这两个进程之间建立管道,所以FIFO实际上也由内核管理,不与硬盘打交道。O_RDONLY(只读方式):调用open()函数的进程将会被阻塞,直到有写方打开管道。原创 2023-06-07 17:31:16 · 487 阅读 · 0 评论 -
linux系统编程—进程—fork和vfork区别
编译运行可以看到子进程一直在输出,父进程并没有打印this is father print。vfork先保证子进程运行,当子进程调用exit退出后,父进程才执行。通过运行结果可以看到,父子进程中的cnt是同一个地址。编译运行可以看到在子进程退出后父进程开始运行。vofork直接使用父进程存储空间,不拷贝。修改部分代码 子进程打印三次后退出。修改部分代码,让父进程打印cnt。原创 2023-06-04 09:12:08 · 94 阅读 · 0 评论 -
linux系统编程—信号携带数据
sigset_t sa_mask: 指定一个信号集,在调用sa_handler所指向的信号处理函数之前,该信号集将被加入到进程的信号屏蔽字中。该函数与signal()函数一样,用于设置与信号sig关联的动作,而oldact如果不是空指针的话,就用它来保存原先对该信号的动作的位置,act则用于设置指定信号的动作。第一个参数是指定接收信号的进程ID,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。信号发送函数sigqueue。原创 2023-06-09 16:48:24 · 211 阅读 · 0 评论 -
linux系统编程—共享内存
而IPC_CREAT | IPC_EXCL则可以创建一个新的,唯一的共享内存,如果共享内存已存在,返回一个错误。IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。参数shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值。参数size指定共享内存的大小,它的值一般为1024的整数倍。原创 2023-06-08 16:33:42 · 118 阅读 · 0 评论 -
linux系统编程—消息队列
对消息队列有读权限的进程则可以从消息队列中读出消息。指定了函数从队列中所取的消息的类型。如果mtype 的值是零的话,函数将不做类型检查而自动返回队列中的最旧(优先级最小的)的消息。IPC_NOWAIT:如果消息队列已满,消息将不被写入队列,控制权返回调用函数的线程。参数key: 消息队列对象的关键字(key),函数将它与已有的消息队列对象的关键字进行比较来判断消息队列对象是否已经创建。从标识符为msgid的消息队列里接收一个指定类型的消息并存储于msgp中读取后把消息从消息队列中删除。原创 2023-06-08 15:52:00 · 635 阅读 · 0 评论 -
linux系统编程—匿名(无名)管道pipe
调用pipe函数,会在内核中开辟出一块缓冲区用来进行进程间通信,pipe函数接受一个参数,是包含两个整数的数组,如果调用成功,会通过pipefd[2]传出给用户程序两个文件描述符,需要注意pipefd[0]指向管道的读端, pipefd[1]指向管道的写端,那么此时这个管道对于用户程序就是一个文件,可以通过read(pipefd [0]);3.父进程关闭读端,子进程关闭写端,父进程可以往管道中进行写操作,子进程可以从管道中读。1.父进程创建管道,得到两个文件描述符分别指向管道的读端和写端。原创 2023-06-07 16:25:28 · 126 阅读 · 0 评论 -
system函数和popen函数
如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数command为空指针(NULL)返回非零值,如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno来确认执行成功。system()会调用fork()产生子进程,由子进程来调用/bin/sh-c command来执行参数command字符串所代表的命令,此命令执行完后随即返回原调用的进程。原创 2023-06-06 10:09:22 · 91 阅读 · 0 评论 -
linux系统编程—exec族函数
fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。linux将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。),也就是这两个进程做完全相同的事。在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事)。原创 2023-06-05 14:06:34 · 78 阅读 · 0 评论 -
linux系统编程—进程—进程的退出、孤儿进程、僵尸进程、wait和waitpid函数
wait函数一般用在父进程中等待回收子进程的资源,而防止僵尸进程的产生。当父进程调用wait()函数时:a. 如果其所有子进程都还在运行,则阻塞;b.只要有一个进程终止,wait就会返回。也就是说只要wait接收到一个SIGCHLD信号,wait()就会返回。对于两个或多个子进程的情况,需要多次调用。c.如果一个子进程已经终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回;d.如果它没有任何子进程,则立即出错返回;原创 2023-06-04 14:13:15 · 285 阅读 · 0 评论 -
linux系统编程—进程—进程创建函数fork
可以看到if语句同时执行了两条,分别被父进程和子进程运行并打印pid,如何证明子进程创建的方式时复制而不是共享,编译以下代码。创建新的子进程后,两个进程共存,他们都将执行fork()函数调用之后的指令。子进程复制了父进程的堆栈段和数据段,并不是共享,他们之间没有任何影响。运行之后发现,父进程打印data值为10 而子进程打印data值为6。,零返回给子进程,正值返回给父进程,正值就是子进程的pid。fork函数不需要参数,当它调用失败时函数返回。,它与进程同时运行,此进程称为。,当调用成功时有两个返回值,原创 2023-06-03 15:28:22 · 235 阅读 · 0 评论 -
linux系统编程—进程相关概念
通常将此段称为bss段,这一名称来源于一个早期的汇编运算符,意思是“block started by symbol”(由符号开始的块),在程序开始执行之前,内核将此段中的数据初始化为0或空指针。通常,正文段是可共享的,所以即使是频繁执行的程序(如文本编辑器、C编译器和shell等)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外而修改其自身的指令。进程:从用户的角度来看进程是程序的一次动态执行过程。如果进程a创建了进程b,那么进程b叫做子进程,a叫做父进程,父子进程是相对概念。原创 2023-06-03 10:34:23 · 64 阅读 · 0 评论 -
linux系统编程—文件编程—利用strstr函数修改文件
返回值:在haystack中查找needle,如果找到,则返回首次出现的地址;如果没找到,则返回NULL。终端输入man strstr查看头文件和相关参数。首先查看编译运行之前该文件的内容。haystack:被查找目标。needle:要查找对象。查看更改之后的文件内容。strstr函数说明。原创 2023-05-18 20:41:47 · 78 阅读 · 1 评论 -
linux系统编程—文件编程—实现cp指令
终端输入 vimdiff xxxx xxxx查看对比两个文件的差异。很明显,这两个文件除了名字一模一样。4.将buf数据写入到目标文件。1.打开需要拷贝的文件。2.读文件数据到buf。3.打开并创建目标文件。5.close两个文件。原创 2023-05-18 16:54:55 · 84 阅读 · 2 评论 -
linux系统编程—文件编程—Read操作编程
打开file2文件,可以看到指针光标在头部,如果不close(fd)重新open而是直接读取,将读取失败。读取成功:返回读取内容的字节数。(返回值不一定等于count,而是实际所读取的值)终端下输入man 2 read查看头文件与相关参数。buf:缓冲区,用于存放读取的内容。fd:需要写入文件的文件描述符。count:要读取的字节大小。读取失败:返回值为-1;原创 2023-05-18 14:34:45 · 218 阅读 · 1 评论 -
linux系统编程—文件编程—lseek函数
在读取文件数据时需要close之后再重新open刷新指针光标,实际上在文件编程中有专门控制指针光标的函数,就是lseek函数。修改上篇文章代码重新打开file2部分,改为用lseek修改指针光标位置。SEEK_SET: 指针光标从文件开头按照传入的offset进行偏移。offset:指针光标的偏移量,为正数时向后偏移,为负数时向前偏移。SEEK_CUR:指针光标从当前位置按照传入的offset进行偏移。SEEK_END:指针光标从文件末尾按照传入的offset进行偏移。fd:需要写入文件的文件描述符。原创 2023-05-18 15:18:09 · 281 阅读 · 1 评论 -
linux系统编程—文件编程—Write操作编程
不能用sizeof计算buf大小,sizeof是一个指针,指针的大小为四,如果用sizeof计算,则只能写入buf的前四个字节。如果写入文件成功,则返回值为写入的字节大小,如果写入失败,则返回值为-1。终端下输入man 2 write 查看头文件与相关参数。fd:需要写入文件的文件描述符。count:写入的字节大小。原创 2023-05-14 11:06:28 · 188 阅读 · 1 评论 -
linux系统编程—文件编程—open函数
为int型文件描述符,值为-1或者非负整数,当打开或创建文件失败时,返回-1,打开成功时返回非负整数,在打开/创建文件时,上述常量是必须使用的,因为他们是互斥关系,故只能选用其中一个。终端输入ll查看文件夹权限,可看到file2文件权限为0600(-rw--)如0600表示-rw------- 0644表示-rw-r--r--为char *型的指针,指针的指向是需要打开或创建的文件路径或文件名。,当我们要对某个文件进行读写操作时,文件描述符的作用就发挥出来了。如果指定文件不存在,则创建这个文件。原创 2023-05-14 09:50:27 · 2067 阅读 · 0 评论 -
Linux系统编程—socket网络编程
套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。sockfd:文件描述符,addr:一个指针指向一个sockaddr结构体,用于存放客户端的地址信息,addrlen:一个指向socklen_t类型变量的指针,用于存放客户端地址结构体的长度。sockfd为socket函数调用返回的文件描述符,my_addr是一个指针,它指向sockfd,addrlen为sockaddr的长度大小。原创 2023-04-20 15:04:43 · 494 阅读 · 1 评论