分类:Linux C

Home / 分类:Linux C

gdb调试中修改变量值

2015-4-11 22:36:25 | Linux C | 没有评论

在调试过程中可以修改变量的值,进而调试程序,这样就避免了修改源代码,重新编译,重新测试的过程

Breakpoint 1, main () at hello.c:4
4           int a = 1;
(gdb) p a
$1 = 0
(gdb) n
5           printf("%d\n", a);
(gdb) p a
$2 = 1
(gdb) set var a=2
(gdb)[......]

Read more

哈希表

2015-2-21 00:37:11 | Linux C | 没有评论

一般的表,如果需要查找某个关键字的记录,就得从表头开始,挨个地比较记录a[i]和key的值是否相等,如果相等就算成功找到了,返回i;假如是有序表来查找,可以通过a[i]和key来二分查找,直到找到相应的i;最终为了找到那个i,其实也就是相对的下标,再通过顺序存储的存储位置来计算,也就是第一个元素内存存储位置加上i-1个单元位置LOC(ai)=LOC(a1)+(i-1)*c,得到最后内存地址

由此可[……]

Read more

再看malloc动态分配内存

2015-2-11 22:40:11 | Linux C | 没有评论

一向对内存敏感性不好,或者说不太有sense,基础恶补恶补很有必要,结合刚看了下一个日本人写的关于malloc的讲解,理清下思路

malloc()是根据参数指定的尺寸来分配内存块,返回指向内存块初始位置的指针,经常用于动态分配结构体的内存领域,分配执行前还不知道大小的数据的内存区域等

p = malloc(size);
free(p);

一旦内存分配失败(内存不足?),malloc()会返回NULL[……]

Read more

移位

2015-2-10 23:33:06 | Linux C | 没有评论

2年前被Boss问了个问题,好像就是变量的倍数如何写,迟疑地问:不是直接乘么?然后结果可想而知,当然当时想要我回答的答案是移位,时过境迁,突然在想,如今这么潮的编译器难道不会优化成移位么

移位<<和>>用于左移和右移,最简单的x<<2将x的值左移两位,右边空出来了两位用0来补,实际上含义就是x乘以4;对于unsigned无符号值进行右移,左边空出来的部分用0来补[……]

Read more

变量入栈顺序

2015-2-10 00:11:40 | Linux C | 没有评论

刚随手打印地址过程中,看到了相同的两个地址

#include <stdio.h>


void fun1(){
    int a1;
    printf("&a1: %p\n", &a1);
}

void fun2(){
    int a2;
    printf("&a2: %p\n", &a2);
}

void main(){
    fun[......]

Read more

socket双向通信

2015-2-9 19:07:25 | Linux C | 没有评论

既然能够进行数据传输,那干脆再试着进行双向数据传输,就变成了简单的命令行聊天室一样,但是需要考虑几个问题

1:socket是否是双向数据传输,幸运的是肯定的

2:如果一端既发送又接收,如何调和的问题,不可能串行一前一后吧,这样发送和接收肯定无法都实时刷新结果,最简单的就是弄两个进程或者两个线程,一个发送一个接收,这里分别通过while(1)来持续操作

下面是分别通过多进程实现,code比较简单随意[……]

Read more

Linux下Socket接收数据长度为0分析

2015-2-9 15:01:35 | Linux C | 没有评论

客户端和服务端已经通过socket建立起了TCP连接,接着可以进行数据传输,这里主要用到send和recv,比较简单,他们和系统调用read和write参数类似

#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
ssize_t recv(int soc[......]

Read more

socket建立连接

2015-2-8 23:19:37 | Linux C | 没有评论

通过pipe,fifo等可以直接同一台机器上进行进程间通信,而通过网络相连的机器之间进行进程间通信要用到套接字接口,实际上套接字可以用在同一台机器上,也可以用在不同的机器上;也就是既可以内部通信,又可以相互之间通信

套接字是通信端点的抽象,和文件描述符一样,访问套接字也需要套接字描述符,处理文件描述符的read,write都可以处理套接字描述符

1:调用socket函数就会创建一个socket描述[……]

Read more

信息存储和字节序

2015-2-8 13:09:19 | Linux C | 没有评论

计算机使用8位字节块作为最小寻址和存储单位,一个字节在二进制里值域为00000000~11111111,十进制就是0~255,而这种表示方法要么太长了,要么转换太麻烦,所以就用十六进制来描述,值域为00~FF,把A的二进制记住就行了,后面就好推算了,当然大脑比较灵活的人啥都不用记,直接心算一遍好了~!

十六进制                        十进制[......]

Read more

Socket套接字

2015-2-1 01:51:13 | Linux C | 没有评论

不论是pipe还是fifo,它们在进程进程间通信时都有资源共享,基本都只能运行在同一台机器上才行,而想要一台机器上的进程和另一台机器上的进程进行数据通信,可以用到socket套接字接口,除了可以与管道相似的方法使用socket之外,套接字还包括了计算机网络中的通信,多台机器进程之间进行通信,更直白一点可以支持网络中的客户端/服务器通信,可是一台机器不同的进程可以通过进程PID来标识区分,网络中却不[……]

Read more

FIFO阻塞读写

2015-1-31 16:12:01 | Linux C | 没有评论

pipe一般都要和fork结合起来用,所以多进程都是基于一个主进程产生的,有一定的关联性,假如两个毫无相关的进程要进行进程间通信,命名管道可以实现;一个进程向FIFO写数据,另一个进程从FIFO读取数据

为了保持原子操作,可以通过阻塞方式来打开FIFO,就算只有一个读进程或者只有一个写进程存在,也会阻塞住等待对应的另一个进程的出现

打开FIFO的方式有下面几种:

open(const char *p[......]

Read more

命名管道FIFO

2015-1-29 00:57:30 | Linux C | 没有评论

fork出来的进程通过普通管道pipe传递数据,而这些进程他们最先都是由一个主进程给构造出来的,也就是有相关性,而如果是想在完全不想关的进程之间传输数据,Linux下可以通过一种特殊的文件来完成,命名管道,它在文件系统中是以文件名的形式存在的

命令行创建命名管道:

[lihui@localhost ~]# mkfifo one
[lihui@localhost ~]# ll one
prw-r--r[......]

Read more

进程管道popen

2015-1-27 22:24:35 | Linux C | 没有评论

python里经常通过popen调用系统命令,并获取命令的输出结果,然后进行二次处理,是十分地简便,比如想查看下当前的Linux系统,直接调用shell命令很容易一行就能解决

#!/usr/bin/env python

import os

print os.popen('cat /etc/issue').read().strip()

[lihui@localhost ~]# ./popen.p[......]

Read more

pipe和fork

2015-1-27 17:30:45 | Linux C | 没有评论

管道看上去也就创造了两个文件描述符,能够读写,好像没能体现出应有的价值,但是假如是要进程间通信,传递数据的时候,只要管道打开的两个文件描述符存在,通过调用fork创建子进程,那么两个进程可以通过管道传递数据,才是真正有用的时候

调用pipe之后,接着调用fork,这样就创建了由主到子(或者子到主)的通道,但是fork之后进程做什么就决定了数据流的方向,下面的简单例子就是从子进程到主进程的方向

#in[......]

Read more

memset

2015-1-27 17:11:28 | Linux C | 没有评论

将buffer所指的内存区域的前count个字节用字符ch替换,对于较大的结构体或者数组清零是个不错的操作

#include <string.h>

void *memset(void *s, int ch, size_t count);

实际上作用就是在一段内存块中填充某个给定的值,比如下面小例子:

#include <stdio.h>
#include <string[......]

Read more

管道

2015-1-27 00:20:14 | Linux C | 没有评论

通常将一个进程的输出通过管道连接到另一个进程的输入,linux下已经对shell命令里管道符号“|”太熟悉了,起到了命令连接的作用,比如命令

[lihui@localhost ~]# lspci | grep Network
0b:00.0 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Conne[......]

Read more

信号量线程同步

2015-1-25 15:50:39 | Linux C | 没有评论

信号量是一种特殊类型的变量,可以被增加和减少,但是对其的访问被保证是原子操作,就算是多线程中也是如此,这样如果多个地方都试图修改信号量的值,能够保证以此进行

二进制信号量只有0和1两种取值,而计数信号量可以设置更大的范围;通常用来保护一段代码,让每次只能被一个执行线程执行,直接通过二进制信号量可实现

线程中用到的信号量函数有下面几个

#include <semaphore.h>
int[......]

Read more

Cygwin和Linux不同环境多线程加锁的差异

2015-1-23 01:00:36 | Linux C | 没有评论

深夜本来都打算弄完睡觉,结果被一个莫名其妙的锁搞得莫名其妙,为了让同步问题明显地表现出来,主线程和子线程都加了一个sleep 1秒,使得都来不及减减操作,if判断就都为真,导致结果变成了-1,但这不是想要的结果

于是想通过互斥量加锁,让一个if以及减减线执行完,然后解锁再执行另一个,可居然还是返回-1,更奇怪的是,去掉两个线程里的sleep,锁就起效果了,难道是这中间的具体实现流程问题没完全弄清楚[……]

Read more

多线程互斥量同步

2015-1-22 23:20:31 | Linux C | 没有评论

多线程在一个进程中有多个控制权,也会有多个函数同时运行,执行各自的CPU指令,就算单CPU,也可以通过线程间指令切换,达到多线程同时运行的效果

并发情况,不同线程之间指令无法确定执行先后顺序,假如这个顺序对运行结果造成影响,那么就会出现竞争,而且会出现问题,要解决竞争可以将原本分离的不同线程间的指令修改成原子操作,那么竞争自然就不存在了

多线程由于可以共享资源,因此同步问题必须要解决,在一定时间区[……]

Read more

线程执行小例子

2015-1-21 23:17:38 | Linux C | 没有评论

虽然成功地创建新的线程,但是需要知道这两个线程是否的确同时都在执行,可以通过一个小例子,这里就不考虑性能运行效率了

这里的想法就是设置一个全局变量,让它在0和1之间跳动,主线程在这个flag为0的时候,就打印0,并将flag赋值为1,而在这个过程当中,子线程沉睡1秒,;同样的接下来子线程在这个flag为1的时候,打印1,并将flag赋值为0,而这个过程中,主线程沉睡1秒,说白了也就是主线程和子线程[……]

Read more

线程终止

2015-1-21 16:03:18 | Linux C | 没有评论

在不终止整个进程的前提下,单个线程可通过pthread_exit退出,它的定义:

#include <pthread.h>

void pthread_exit(void *rval_ptr)

参数rval_ptr无类型指针,与创建线程最后一个参数传给子线程的参数类型一致,其它线程可以通过pthread_join访问这个指针

#include <pthread.h>
int p[......]

Read more

简单创建线程

2015-1-21 01:24:55 | Linux C | 没有评论

线程和进程一样,也有唯一的线程ID,它的类型是pthread_t

在Linux里定义如下:

/* Thread identifiers.  The structure of the attribute type is not
   exposed on purpose.  */
typedef unsigned long int pthread_t;

而Windows下是一个结构体定义,Cygwin[……]

Read more

线程概念

2015-1-20 23:55:06 | Linux C | 没有评论

线程个人觉得比进程更有必要好好钻研一把,天天配置CPU Affinity,天天给每个线程绑定对应的Core ID,却没有从根本上弄明白机理,是一件十分尴尬的事情,无脑的东西不是应该崇尚的,APUE上关于线程概念写的十分漂亮,就直接COPY过来,然后加一些自己的理解,理论还是要透彻点

典型的UNIX进程可以看成是只有一个控制线程:一个进程在同一时刻只做一件事情;但有了多个控制线程以后,可以把进程设计[……]

Read more

信号

2015-1-18 20:42:47 | Linux C | 没有评论

Linux里信号是系统响应了某些条件而生成的一个事件,捕获到该信号的进程会相应地采取一些行动;信号是由于某些错误条件造成的,比如内存段冲突,浮点处理器错误或者非法指令等;它们由shell和终端处理器生成来引起中断,还可以作为在进程间传递消息或者修改行为的一种方式,明确地由一个进程发送给另一个进程

所有信号都在头文件signal.h里定义,以SIG开头,有兴趣可以自行搜索

如果进程接收到一个信号,但[……]

Read more

僵尸进程

2015-1-18 14:53:12 | Linux C | 没有评论

子进程是父进程调用fork生成的,如果父进程在子进程之前结束,那么对于对应的父进程都已经结束的所有子进程,它们的父进程都会变成init进程,也就是这些子进程被init进程领养;在一个进程结束时,内核会逐个检查所有的活动进程,来判断它是否是正要结束的子进程,如果是,就会将该进程的父进程ID改为1,也就是init这个进程,如此就保证了每个进程都有一个父进程

如果子进程在父进程之前结束,子进程会将其结束[……]

Read more

进程等待

2015-1-18 01:43:43 | Linux C | 没有评论

通过调用fork创建了一个子进程,通过返回值来判断,但始终无法并不知道结束顺序,比如下面在两个进程中,最后都分别执行message内容,并sleep 1秒钟,不过子进程执行了3次,而父进程仅仅执行一次,就会出现奇怪的现象~!

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()[......]

Read more

fork多进程

2015-1-15 23:36:29 | Linux C | 没有评论

每个进程都有一个非负整数的PID,可以通过下面函数返回

#include <unistd.h>

//进程ID
pid_t getpid(void);

//父进程ID
pid_t getppid(void);

而调用fork函数可以创建新进程,即子进程;fork被调用一次,就好像copy了一份副本,返回两次,父进程的返回值是子进程的进程ID,子进程的返回值是0

在调用fork之后,子进[……]

Read more

标准IO库缓冲区

2015-1-14 01:09:41 | Linux C | 没有评论

看到标准IO库,总会不自然地往回翻文件IO的部分

文件IO里的read,write都是内核态系统调用,依赖于操作系统来对文件进行读写,虽然速度快,但都是不带缓冲的,而且之前有写IO的效率,CPU用时还与其中一个参数每次读取的字节数相关

标准库IO会先在内存开辟一个缓冲区,给程序中文件来使用,比如执行读操作,先从磁盘文件将数据读入内存缓冲区,满了之后再从内存缓冲区一次读入;写操作先将数据写入内存缓冲[……]

Read more

延迟写

2015-1-3 23:32:07 | Linux C | 没有评论

传统UNIX实现在内核中设有缓冲区高速缓存或者页面高速缓存,大多数磁盘IO都通过缓冲进行;当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的IO操作,这种输出方式称为延迟写(delayed write)

这是Steven[……]

Read more

十个值得关注的c开源项目

2014-12-26 20:59:22 | Linux C | 没有评论

前几天让同事有福推荐点开源软件研究下,随口给我推荐了cJSON,然后其它还有一些都写在了他的个人主页上,我就直接转过来了,当然转载的要厚道,有兴趣可以关注他写的其它内容,传送门:http://youfu.xyz

这个文章是在知乎看到别人推荐,觉得说的挺不错摘抄过来的。
这个上面的加上上一篇编程水平进阶之路,我觉得够c程序员吃一壶的了。

1. Webbench

Webbench是一个在linux下使用[……]

Read more

如何动手更solid

2014-12-25 23:32:59 | Linux C | 没有评论

Boss有句口头禅:“XXXX做得不solid”!由于这个[‘salid’]读音很发人深省因此在我们同事之间广为流传!

今天在调试的时候,很流利地重写了一些代码,令人费解的是死活不出结果,自我感觉应该很solid呀,刚刚才发现是为了调试json结构体的type其中两种情况true和false的意义,将需要处理的json文件多添加了一行“lihui”:why,当时为了确认如果是true/false是[……]

Read more

cJSON库之解析json部分

2014-12-24 23:55:24 | Linux C | 没有评论

cJSON是一个处理json的开源C库,它有构造json和解析json文件两部分,由于还没完全摸索完,先将解析json这部分钻研下

处理json是一个用的比较多的过程,用脚本语言的话应该python最简单了,内置字典类型,想得到json文件里的key-value的话:

pf = open(json_file, ‘r’)

decode_json = json.load(pf)

print decod[……]

Read more

陈黑客介绍libpcap

2014-12-18 22:55:02 | Linux C | 没有评论

这篇摘抄自背后同事有福大神,作为黑客的他他已经成功在乌云漏洞平台提交了多个漏洞,想膜拜的可以传送到:youfu.xyz,除此之外在公司做了快4年底层的他,libpcap应该是手到擒来,我觉得这篇写的比较有特色,不是那么千篇一律念文字废话连篇,就残忍地COPY过来了,方便我以后用的时候查阅

查看pcap.h文件, 可以看到libpcap给出的对外接口。
平时使用libpcap捉包常用的数据结构和API[……]

Read more