[C] C Programming Language

C Programming Language

Contents

function



编译

Blog

C99标准

gcc src.c -std=c99 -o src

运行

gdb

gcc fileclient.c -g -o client
gdb client
ll
gcc fileclient.c -g -o client
gdb client
gcc fileclient.c -g -o client
gdb client
gcc fileclient.c -g -o client
gdb client
cd ../..
ll
cd socketfile/
ll
cd iclient/
ll
rm -rf color.txt rove.txt test.xlsx client


flags = fcntl(sockfd, F_GETFL, 0);                       
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);   

flags  = fcntl(sockfd,F_GETFL,0);
fcntl(sockfd,F_SETFL,flags&~O_NONBLOCK); 

gdb 使用方法


Thread Process

Blog

Thread Process

Basic

同一进程中的多条进程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。

但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register)、自己的线程本地存储(thread-local starage).

一个进程可以有很多线程,每个线程执行不同的任务。

进程的组成:程序+数据集合+PCB(程序控制块)

PCB:包含进程的描述信息和控制信息,是进程存在的唯一标志

进程的基本特征:动态性+并发性+独立性+结构性

  1. 动态性:进程是程序的一次执行过程,是临时的,有生命周期的,是动态产生,动态消亡的;
  2. 并发性:任何进程都可以同其他进程一起并发执行;
  3. 独立性:进程是系统进行资源分配和调度的一个独立单位;
  4. 结构性:进程由程序、数据和进程控制块三部分组成。

Linux进程间通信

  1. 管道(pipe)及有名管道(named pipe)
  2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程的某种事件,除了用于进程间通信外,进程还可以发送信号给进程本身。
  3. 报文(Message)队列信息(消息队列):
  4. 共享内存:
  5. 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段
  6. 套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程通信。

include

#include 
// Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a
//因此在编译时要加上-lpthread选项
-lpthread

pthread_create()

pthread()用来创建线程并启动

int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (start_routine)(void ), void * arg);

thread:线程指针
attr:线程属性指针,pthread_attr_t用来指定线程优先级等属性
void *:函数指针,线程要执行的代码
arg:传递给func的参数
返回值:0               成功
        errorcode       错误

pthread_cancel()

一个线程可以调用pthread_cancel终止同一进程中的另一个线程

int pthread_cancel(pthread_t thread);

pthread_exit()

extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));

pthread_join()

线程等待

main函数执行的线程称为主线程,多线程的执行顺序由线程调度决定

等待线程结束,这个函数是一个线程阻塞函数。调用他的函数将一直等待到线程结束为止。

pthread_join(t1,NULL);
第一个参数t1:线程ID
第二个参数:用来接受线程函数的返回值

pthread_self()

获取当前线程的线程TID

-lpthread

linux下编译C代码时error:undefined reference to sem_init sem_wait解决方法之一
因为pthread并非Linux系统的默认库,编译时注意加上-pthread参数,以调用连接库

  gcc -o server.out server.c -lpthread

sem_wait()

是一个原子操作,作用为从信号量的值减去一个“1”

sem_init()

sem_init()函数是Posix信号量操作中的函数
sem_t,信号量的数据类型

int sem_init(sem_t *sem, int pshared, unsigned int value);

sem :      //指向信号量对象,指向信号量结构的一个指针
pshared :   //指明信号量的类型。不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享。
value :     //指定信号量值的大小

pthread_t

类型变量
用于声明线程ID,线程结构,用来保存线程的相关数据,可理解为线程类型,声明一个线程对象(变量)

void *

C语言中void * 为 “不确定类型指针”,void *可以用来声明指针

sem_init

sigset_t

信号集及信号集操作函数:信号集被定义为一种数据类型,主要与信号阻塞相关函数配合使用。

typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t

//信号集操作定义的相关函数
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum)
int sigdelset(sigset_t *set, int signum);
int [sigismember](https://baike.baidu.com/item/sigismember)(const sigset_t *set, int signum);
int sigaction( int sig, const struct sigaction *act,struct sigaction *oact );
头文件
#include 
sigemptyset(sigset_t *set)初始化由set指定的信号集,信号集里面的所有信号被清空;
sigfillset(sigset_t *set)调用该函数后,set指向的信号集中将包含linux支持的62种信号;
sigaddset(sigset_t *set, int signum)在set指向的信号集中加入signum信号;
sigdelset(sigset_t *set, int signum)在set指向的信号集中删除signum信号;
[sigismember](https://baike.baidu.com/item/sigismember)(const sigset_t *set, int signum)判定信号signum是否在set指向的信号集中。
int sigaction( int sig, const struct sigaction *act,struct sigaction *oact )[检查](https://baike.baidu.com/item/%E6%A3%80%E6%9F%A5)、修改和指定信号相关联的信号响应。

Linux Unix select()

博客

select()函数

作用:多路检测可用套接字

返回:满足条件的套接口的数目

select()

#include  
#include  
int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout);
int select(int nfds, fd_set *readset, fd_set *writeset,fd_set* exceptset, struct tim *timeout);

nfds:需要检查的文件描述字个数(即检查到fd_set的第几位),数值应该比三组fd_set中所含的最大fd值更大,一般设为三组fd_set中所含的最大fd值加1(readset, writeset, exceptset  中的最大值为5,则nfds=6,因为fd是从0开始的)

readset:用来检查可读性的一组文件描述字
writeset:用来检查可写性的一组文件描述字
exceptset:用来检查是否有异常条件出现的文件描述字
timeout:用来描述一段时间长度,如果在这个时间内需要监视的描述符没有事件发生函数返回,返回值为0,阻塞:NULL,

maxfd:需要监视的最大的文件描述字值+1
struct timeval:结构用于描述一段时间长度,如果在这个时间内,需要监视的描述字没有事件发生则返回函数,返回值为0
fd_set:是一组文件描述字(fd)的集合,它用一位来表示一个fd,对于fd_set类型通过下面四个宏来操作:
{
    FD_ZERO(fd_set *fdset); //将指定的文件描述字集清空,在对文件描述字集合进行设置前,必须对其进行初始化,如如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。
    FD_SET(fd_set *fdset);  //用于在文件描述字集合中增加一个新的文件描述符
    FD_CLR(fd_set *fdset);  //用于在文件描述符集合中删除一个文件描述符
    FD_ISSET(int fd,fd_set *fdset)  //用于测试指定的文件描述符是否在该集合中
}

STDIN_FILENO:接收键盘的输入
STDOUT_FILENO:向屏幕输出

Function(Learning) Home

inet_pton() & inet_npton()

Features:将IP地址在“点分十进制”和“二进制整数”之间转换

inet_pton();“点分十进制”到“二进制整数”

inet_nton();“二进制整数”到“点分十进制”

WINDOWS:
#include 

LINUX:
#include 
#include 
#include


int inet_pton(int af, const char *src, void *dst){
    af = AF_INET    //第一个参数af是地址簇
    *src            /*第二个参数*src是来源地址,
                    af设置为AF_INET,src为指向字符型的地址(ddd.ddd.ddd.ddd格式),
                    函数将该地址转换为in_addr的结构体,并复制在*dst中*/
    *dst            //第三个参数* dst接收转换后的数据
    
    af = AF_INET6   //第一个参数af是地址簇
    *src             /*为指向IPV6的地址,函数将该地址转换为in6_addr的结构体,并复制在*dst中*/
    *dst            //第三个参数* dst接收转换后的数据
}


inet_npton(){
   const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); 
}

atoi()

Features: ascii to integer

int atoi(const char *nptr);

htons()

Features: 主机字节顺序 to 网络字节顺序,就是整数在地址空间存储方式变为高位字节存放在内存的低地址处。网络字节顺序采用

htons() host to network short
htonl() host to network long
ntohs() network to host short
ntohl() network to host long

memset()

结构体或数组进行清零操作的一种最快方法

//函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
void *memset(void *s, int ch, size_t n);

bzero()

//bzero()会将参数s 所指的内存区域前n 个字节,全部设为零值
extern void bzero(void *s, int n)

string function

strcmp()

String comparison

int strcmp(const char *str1, const char *str2)

strcpy()

string copy


strcat()


文件操作

你可能感兴趣的:([C] C Programming Language)