• 线程基本操作(一)


    一、简介

      使用线程函数库,需要引入头文件<pthread.h>

      链接这些线程函数库时要使用编译命令的“ -lpthread” 选项

    二、函数介绍

      1、创建一个新的线程

      原型

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

      参数

        thread:返回线程的ID

        attr:设置线程的属性,attr为NULL表示使用默认的属性

        start_routine:时函数地址,线程启动后要执行的函数

        arg:传给线程启动函数的参数

      返回值:  

        成功返回0;失败返回错误码

      2、等待线程结束

      原型

        int pthread_join(pthread_t thread, void **retval);

      参数

        thread:线程ID

        retval:指向一个指针,后者指向线程的返回值

      返回值:

        成功返回0;失败返回错误码 

      3、线程终止

      原型

        void pthread_exit(void *retval);

      参数:

        retval:不要指向一个局部变量

      返回值:

        无返回值,跟进程一样,线程结束的时候无法返回到他的调用者

      4、返回 线程ID

      原型:

         pthread_t pthread_self(void);

      返回值:

        返回 线程ID

      5、取消一个执行中的线程

      原型:

        int pthread_cancel(pthread_t thread);

      参数:

        thread:线程ID

      返回值:

        成功返回0;失败返回错误码

      6、讲一个线程分离

      原型:

        int pthread_detach(pthread_t thread);

      参数:

        thread:线程ID

      返回值:

        成功返回0;失败返回错误码

    使用线程实现回射客户/服务器程序:

    echocli.c

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    #define ERR_EXIT(m) 
            do 
            { 
                    perror(m); 
                    exit(EXIT_FAILURE); 
            } while(0)
    
    
    void echo_cli(int sock)
    {
        char sendbuf[1024] = {0};
            char recvbuf[1024] ={0};
            while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
            {
                    write(sock, sendbuf, strlen(sendbuf));
                    read(sock, recvbuf, sizeof(recvbuf));
    
                    fputs(recvbuf, stdout);
                    memset(sendbuf, 0, sizeof(sendbuf));
                    memset(recvbuf, 0, sizeof(recvbuf));
            }
    
            close(sock);
    }
    
    int main(void)
    {
        int sock;
        if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
            ERR_EXIT("socket");
    
        struct sockaddr_in servaddr;
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(5188);
        servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
        if (connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
            ERR_EXIT("connect");
    
        echo_cli(sock);
    
        return 0;
    }

    echosrv.c

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    #define ERR_EXIT(m) 
            do 
            { 
                    perror(m); 
                    exit(EXIT_FAILURE); 
            } while(0)
    
    void echo_srv(int conn)
    {
        char recvbuf[1024];
            while (1)
            {
                    memset(recvbuf, 0, sizeof(recvbuf));
                    int ret = read(conn, recvbuf, sizeof(recvbuf));
            if (ret == 0)
            {
                printf("client close
    ");
                break;
            }
            else if (ret == -1)
                ERR_EXIT("read");
                    fputs(recvbuf, stdout);
                    write(conn, recvbuf, ret);
            }
    }
    
    void* thread_routine(void *arg)
    {
            pthread_detach(pthread_self());//使用线程分离避免僵线程
            int conn = *((int*)arg);
            free(arg);
            echo_srv(conn);
            printf("exiting thread ...
    ");
            return NULL;
    }
    
    int main(void)
    {
        int listenfd;
        if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
            ERR_EXIT("socket");
    
        struct sockaddr_in servaddr;
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(5188);
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        int on = 1;
        if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
            ERR_EXIT("setsockopt");
    
        if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
            ERR_EXIT("bind");
        if (listen(listenfd, SOMAXCONN) < 0)
            ERR_EXIT("listen");
    
        struct sockaddr_in peeraddr;
        socklen_t peerlen = sizeof(peeraddr);
        int conn;
    
        while (1)
        {
            if ((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0)
                ERR_EXIT("accept");
    
            printf("ip=%s port=%d
    ", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));

    pthread_t tid; int ret; int *p = malloc(sizeof(int)); *p = conn; //if((ret = pthread_create(&tid,NULL,thread_routine,(void*)conn)) != 0)不同系统int占用字节不同,不便于移植不同系统int占用字节不同,不便于移植 if((ret = pthread_create(&tid,NULL,thread_routine,p)) != 0) { fprintf(stderr,"pthread_create:%s ",strerror(ret)); exit(1); } } return 0; }

    线程传参方式:

    #include <stdio.h>
    #include <pthread.h>
    #include <time.h>
    
    typedef struct _date{
            int year;
            int mon;
            int day;
    }DATE;
    
    void thread_fun1(void *arg)
    {
            int num =*(int *)arg;
            free(arg);
            printf("num = %d
    ",num);
    }
    
    void thread_fun2(void *arg)
    {
            DATE *date;
            date = (DATE *)arg;
            int year = date->year;
            int mon = date->mon;
            int day = date->day;
            free(arg);
            printf("date = %d: %d: %d
    ",year,mon,day);
    
    }
    
    int main(void)
    {
            struct tm *local;
            time_t t;
            t=time(NULL);
            local=localtime(&t);
    
            pthread_t tid1,tid2;
            int *p = NULL;
            p = (int *)malloc(sizeof(int));
            *p = 10;
            pthread_create(&tid1,NULL,thread_fun1,(void*)p);
    
            DATE *date;
            date = (DATE *)malloc(sizeof(DATE));
            date->year = local->tm_year;
            date->mon = local->tm_mon;
            date->day = local->tm_mday;
            pthread_create(&tid2,NULL,thread_fun2,(void*)date);
    
            pthread_join(tid1,NULL);
            pthread_join(tid2,NULL);
    
            return 0;
    }
  • 相关阅读:
    IE input X 去掉文本框的叉叉和密码输入框的眼睛图标
    vue监听滚动事件 实现某元素吸顶或者固定位置显示
    判断滚动条到底部的JS逻辑
    vue plugin 插件编写以loading为例
    Maven使用yuicompressor-maven-plugin打包压缩css、js文件
    AngularJS 用 Interceptors 来统一处理 HTTP 请求和响应
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
    angular内ng存在属性是专门用来解决跨域问题的,$sce
    dede上怎么让所有链接在新窗口打开
    dede文章页调用当前栏目链接方法
  • 原文地址:https://www.cnblogs.com/Malphite/p/7789979.html
Copyright © 2020-2023  润新知