• linux下c编程入门笔记


    一、基础知识

    源程序编译

    /***hello.c***/

    int main() {printf("hello,world. "); return 0;}

    gcc -o hello hello.c

    -o生成可执行文件

    -c只输出目标代码

    -g可调试

    makefile编写

    ####makefile1####

    main: main.o t1.o t2.o

      gcc -o $@ $^

    main.o: main.c t1.h t2.h

      gcc -c $<

    t1.o: t1.c t1.h

      gcc -c $<

    t2.o: t2.c t2.h

      gcc -c $<

    $@##目标文件

    $^##所有依赖文件

    $<##第一个依赖文件

    ####makefile2####

    main: main.o t1.o t2.o

      gcc -o $@ $^

    ..c.o

      gcc -c $<

    ##自动推导

    程序库的连接

    -lm数学库

    -lpthread线程库

    系统的缺省库路径:/lib, /usr/lib, /usr/local/lib

    否则要指定连接路径:-L/home/ming/mylibs -lming 这样就会到相应目录下连接libming.so|libming.a

    调试

    参考gdb入门

    帮助

    man write ###write命令的帮助

    man 2 write ###系统调用函数的帮助

    man 3 write ###C库函数的帮助

    二、进程

    进程概念

    进程是程序的执行过程,即一个开始执行但没有结束的程序的实例。每个进程可以有多个子进程...

    为了区分不同的进程,系统给每个进程分配了唯一的id以示区别

    进程的状态:新建、运行、阻塞、就绪、完成

    个人理解:linux下的多线程根本上都是多个子进程,分别拥有自己的进程id,但没有自己的进程名,与之对应的父进程的程序名。

    查看进程命令:ps, 如:ps -ef, ps -aux

    进程的标志

    #include <unistd.h>

    pid_t getpid();//获得进程id

    pid_t getppid();//获得父进程id

    进程是为程序服务的,程序是为用户服务的。系统为了找到进程的用户名,为进程和用户建立了联系。这个用户成为进程的所有者,相应的每个用户也有一个用户id。用户隶属不同的组,每个组也有自己的id。

    #include<unistd.h><sys/types.h>

    uid_t getuid();//获得进程所有者用户id

    uid_t geteuid();//获得进程的有效用户id

    gid_t getgid();//获得组id

    gid_t getegid();//获得有效组id

    进程的创建

    #include<unistd.h>

    pid_t fork();//创建进程

    对于父进程fork()返回子进程的id,对于fork子进程返回0,创建进程失败返回-1。一旦子进程被创建,就与父进程一起从fork处继续执行,相互竞争系统的资源。如果希望子进程执行,而父进程阻塞直到子进程完成,这是可以调用wait()或waitpid()函数。

    父进程创建子进程后,子进程一般要调用不同的程序。为了调用系统程序,可以使用如下的exec族的函数:

    #include<unistd.h>

    int execl(char*path,char*arg,...);

    int execlp(char*file,char*arg,...);

    int execle(char*path,char*arg,...);

    int execv(char*path,char*argv[]);

    int execvp(char*file,char*argv[]);

    /********forktest.c**********/

    #include<unistd.h><sys/types.h><sys/wait.h><stdio.h><errno.h><math.h>

    void main()

    {

      pid_t child;

      int status;

      if((child = fork()) == -1) exit(1);

      else if(child == 0)

      {

        int i;

        printf("i am the child: %ld ", getpid());

        for(i=0; i<1000000; i++) sin(i);

        exit(5);

      }

      while(((child=wait(&status))==-1)&&(errno==EINTR));

      if(child == -1)printf("wait error: %s ", strerror(errno));

      else if(!status);

      else {...}

    }

    守护进程

    /****checkmail.c****/

    #include<unistd.h><sys/types.h><sys/stat.h><stdio.h><errno.h><fcntl.h><signal.h>

    #define MAIL "/var/spool/mail/ming"

    #define SLEEP_TIME 10

    void main()

    {

      pid_t child;

      if((child=fork())==-1)exit(1);

      else if(child>0)while(1);

      if(kill(getppid(),SIGTERM)==-1)exit(1);

      int mailfd;

      while(1)

      {

        mailfd=open(MAIL,O_RDONLY);

        close(mailfd);

        sleep(SLEEP_TIME);

      }

    }

    三、文件操作

    文件读写

    /*****filerw.h****/

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <sting.h>
    #define BUF_SIZE 1024
    int main(int argc, char** argv)
    {
        int from_fd, to_fd;
        int bytes_read, bytes_write;
        char buf[BUF_SIZE];
        char* ptr;
        if(argc != 3) {
            fprintf(stderr, "Usage: %s fromfile tofile a", argv[0]);
            exit(1);
        }
        if((from_fd = open(argv[1], O_RDONLY)) == -1) exit(1);
        if((to_fd = open(argv[2], O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)) == -1) exit(1);
        while(bytes_read = read(from_fd, buf, BUF_SIZE))
        {
            if((bytes_read = -1) && (errno != EINTR)) break;
            else if(bytes_read > 0) {
                ptr = buf;
                while(bytes_write = write(to_fd, ptr, bytes_read))
                {
                    if((bytes_write == -1) && (errno != EINTR)) break;
                    else if(bytes_write == bytes_read) break;
                    else if(bytes_write > 0) {
                        ptr += bytes_write;
                        bytes_read -= bytes_write;
                    }
                    if(bytes_write == -1) break;
                }
            }
        }
        close(from_fd);
        close(to_fd);
        return 0;
    }

    目录操作

    /******dir_opt.c********/
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <time.h>

    static int get_file_size_time(const char* filename)
    {
        struct stat statbuf;
        if(stat(filename, &statbuf) == -1) return -1;
        if(S_ISDIR(statbuf.st_mode)) return 1;
        if(S_ISREG(statbuf.st_mode)) {
            printf("%s size: %ldbytes modified at %s ", filename, statbuf.st_size, ctime(&statbuf.st_mtime));
        }
        return 0;
    }
    int main(int argc, char** argv)
    {
        DIR* dirp;
        struct dirent* direntp;
        int stats;
        if(argc != 2) {
            printf("Usage: %s filename a", argv[0]);
            exit(1);
        }
        if(((stats = get_file_size_time(argv[1])) == 0) || (stats == -1)) exit(1);
        if((dirp = opendir(argv[1])) == NULL) {
            exit(1);
        }
        while((direntp = readdir(dirp)) != NULL);
        closedir(dirp);
        return 0;
    }

    管道文件

    /********pipe.c*********/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #define BUFFER 255

    int main(int argc, char** argv)
    {
        char buffer[BUFFER+1];
        int fd[2];
        if(argc != 2) {
            fprintf(stderr, "Usage: %s string a", argv[0]);
            exit(1);
        }
        if(pipe(fd) != 0) exit(1);
        if(fork() == 0) {
            close(fd[0]);
            printf("child[%d] write to pipe. ", getpid());
            snprintf(buffer, BUFFER, "%s", argv[1]);
            write(fd[1], buffer, strlen(buffer));
            printf("child[%d] quit. ", getpid());
            exit(0);
        }
        else {
            close(fd[1]);
            printf("parent[%d] read from pipe ", getpid());
            memset(buffer, 0, BUFFER+1);
            read(fd[0], buffer, BUFFER);
            printf("parent[%d] read: %s ", getpid(), buffer);
            exit(1);
        }
        return 0;
    }

    四、时间

    时间表示

    #include <sys/time.h>

    time_t time(time_t* tloc);//返回1970年至今的秒数

    char* ctime(const time_t* clock);//返回类似"Fri Nov 7 13:40:58 2014"字符串

    gettimeofday();//获得一天内的时间

    计时器

    todo......

    五、信号处理

    todo

    六、消息管理

    todo

    七、线程操作

    子进程是通过拷贝父进程的地址空间来执行的,线程是通过共享程序代码来执行的。

    -lpthread连接线程库

    #include <pthread.h>

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

    void pthread_exit(void* retval);

    int pthread_join(pthread* thread, void** thread_return);

    简易生产者-消费者实现:

    #include <stdio.h>
    #include <pthread.h>
    int count = 0;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    void* producer(void* argv) {
        while (1) {
            pthread_mutex_lock(&mutex);
            count++;
            pthread_mutex_unlock(&mutex);
            pthread_cond_signal(&cond);
            sleep(1);
        }
        return NULL;
    }
    void* consumer(void* argv) {
        while (1) {
            pthread_mutex_lock(&mutex);
            pthread_cond_wait(&cond, &mutex);
            printf("count = %d ", count);
            pthread_mutex_unlock(&mutex);
        }
        return NULL;
    }
    int main() {
        pthread_t t1=0, t2=0;
        pthread_create(&t1, NULL, producer, NULL);
        pthread_create(&t2, NULL, consumer, NULL);
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
        return 0;
    }

    生产者-消费者实例2

    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>
    int count = 0;
    sem_t sem;
    void* producer(void* argv) {
        while (1) {
            count++;
            sem_post(&sem);
            sleep(1);
        }
        return NULL;
    }
    void* consumer(void* argv) {
        while (1) {
            sem_wait(&sem);
            printf("count=%d ", count);
        }
        return NULL;
    }
    int main() {
        sem_init(&sem, 0, 0);
        pthread_t t1 = 0;
        pthread_t t2 = 0;
        pthread_create(&t1, NULL, producer, NULL);
        pthread_create(&t2, NULL, consumer, NULL);
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
        sem_destroy(&sem);
        return 0;
    }

    八、网络编程

    tcp_server.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #define MAXLINE 80
    int main() {
        int listenfd, connfd;
        int n, i;
        struct sockaddr_in servaddr, cliaddr;
        socklen_t cliaddr_len;
        char buf[MAXLINE];
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(8888);
        bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
        listen(listenfd, 10);
        while (1) {
            cliaddr_len = sizeof(cliaddr);
            connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len);
            n = read(connfd, buf, MAXLINE);
            for (i = 0; i < n; i++) {
                buf[i] = toupper(buf[i]);
            }
            write(connfd, buf, n);
            close(connfd);
        }
        return 0;
    }

    tcp_client.c

    int main() {
        struct sockaddr_in servaddr;
        char buf[MAXLINE];
        int sockfd, n;
        char* str = "hello,world.";
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
        servaddr.sin_port = htons(8888);
        connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
        write(sockfd, str, strlen(str));
        n = read(sockfd, buf, MAXLINE);
        write(STDOUT_FILENO, buf, n);
        close(sockfd);
        return 0;
    }

    udp_server.c

    #define MAXLINE 80
    int main() {
        struct sockaddr_in servaddr, cliaddr;
        socklen_t cliaddr_len;
        int sockfd;
        char buf[MAXLINE];
        int i,n;
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(8888);
        bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
        while (1) {
            cliaddr_len = sizeof(cliaddr);
            n = recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr*)&cliaddr, &cliaddr_len);
            for (i = 0; i < n; i++) {
                buf[i] = toupper(buf[i]);
            }
            n = sendto(sockfd, buf, n, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
        }
        return 0;
    }

    udp_client.c

    #define MAXLINE 80
    int main() {
        struct sockaddr_in servaddr;
        int sockfd, n;
        char buf[MAXLINE];
        socklen_t servaddr_len;
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
        servaddr.sin_port = htons(8888);
        while (fgets(buf, MAXLINE, stdin) != NULL) {
            n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
            n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
            write(STDOUT_FILENO, buf, n);
        }
        return 0;
    }

  • 相关阅读:
    多表模型
    母版,单表操作,双下划线模糊查询
    模板层
    视图层
    路由层
    orm
    浅谈cookie,sessionStorage和localStorage区别
    实现元素垂直居中的方法(补充)
    实现元素垂直居中的方法
    <a href="javascript:;"></a>
  • 原文地址:https://www.cnblogs.com/feilv/p/4081208.html
Copyright © 2020-2023  润新知