• step4 . day6 线程与线程的创建


    1.什么是线程:线程是轻量级的进程,占用资源少,同一个进程的线程共享相同的地址空间,线程间切换时间少

    2.线程概念分类:同步线程,互斥线程(防止同时修改临界资源),线程的PV操作等

    3.线程相关命令 ps -eLf 查看所有线程,线程编译要链接库  -lpthread

    4.线程相关函数

    1)线程创建:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

                                                                  tid(出错不能用perror打印)     线程属性null             线程回调函数              给线程函数传参(可以传值,强转)

    线程注意事项:①线程里面不可以写exit,否则整个进程都退出,②main函数退出,整个程序就退出,线程不存在,③线程执行完毕线程关闭,资源不回收

    2)线程回收:

    pthread_join函数 对应进程的 waitpid

    pthread_exit 线程退出函数 对应进程的 exit,返回的值可以被pthread_join函数接受

    3)线程取消:  pthead_cancel  一个线程可以取消另外一个线程(不保证结果)。添加pthread_testcancel()函数保证线程可以被正常取消

    4)线程的detach:int pthread_detach(pthread_t thread),设置线程为detach属性,这样线程退出资源自动释放,无需使用pthread_join(pthread_self(),自己线程tid)

    5.线程相关demo代码

    1)两个线程干不同是事情

    #include <stdio.h>
    #include <pthread.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <time.h>
    #include <unistd.h>

    #define N 32

    void *timewrite(void *arg);
    void *scanfwrite(void *arg);

    int main(int argc, const char *argv[])
    {

    pthread_t tid1,tid2;
    int re1,re2;
    re1 = pthread_create(&tid1,NULL,timewrite,NULL);
    if(re1){
    printf("pthread_create 1:%s ",strerror(re1));
    return -1;
    }
    re2 = pthread_create(&tid2,NULL,scanfwrite,NULL);

    pthread_detach(tid1);
    if(re2){
    printf("pthread_create 1:%s ",strerror(re2));
    return -1;
    }

    pthread_detach(tid1);
    sleep(60);

    pthread_cancel(tid1);
    pthread_cancel(tid2);

    return 0;
    }

    void *timewrite(void *arg){

    FILE *fp;
    fp = fopen("timelog.txt", "w");
    if(fp == NULL){
    perror("fopen timelog");
    return NULL;
    }

    while(1){
    time_t t = time(&t);
    char buf[N] ={0};
    strcpy(buf,ctime(&t));
    fwrite(buf,1,strlen(buf),fp);
    sleep(1);
    pthread_testcancel();
    }
    }


    void *scanfwrite(void *arg){

    int fd;
    char buf[N]={0};
    fd = open("scanflog.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);
    if(fd < 0){
    perror("open scanflog");
    return NULL;
    }

    while(1){

    fgets(buf, N, stdin);

    write(fd,buf,strlen(buf));

    pthread_testcancel();

    }

    2)线程锁,防止线程同时修改临界资源区(死锁是线程相互等待各自资源,避免死锁方案①一次申请②使用一个锁)


    #include <stdio.h>
    #include <pthread.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>


    pthread_mutex_t lock;

    void * writefunc(void *arg){
    int fd1;
    char buf[32];
    strcpy(buf,(char*)arg);

    pthread_mutex_lock(&lock);
    fd1 = open("log.txt",O_APPEND|O_WRONLY);
    printf("buf = %s ",buf);
    write(fd1,buf,strlen(buf));
    close(fd1);
    pthread_mutex_unlock(&lock);

    }

    int main(int argc, const char *argv[])
    {


    int re1,re2;
    pthread_t tid1,tid2;
    char *buf1 = "hello world ";
    char *buf2 = "how are you ";
    int fd;

    pthread_mutex_init(&lock,NULL);

    fd = open("log.txt", O_CREAT|O_TRUNC,0777);
    if(fd<0){
    perror("open");
    return -1;
    }
    close(fd);

    re1 = pthread_create(&tid1, NULL,writefunc,(void*)buf1);
    if(re1){
    printf("pthread_create 1:%s ",strerror(re1));
    return -1;
    }
    pthread_detach(tid1);

    re2 = pthread_create(&tid1, NULL,writefunc,(void*)buf2);
    if(re2){
    printf("pthread_create 1:%s ",strerror(re2));
    return -1;
    }
    pthread_detach(tid2);

    sleep(10);
    return 0;
    }

    3)线程的PV操作(生产者消费之概念)


    sem_t sem;

    void * writefunc1(void *arg){
    int fd1;
    char buf[32];
    strcpy(buf,(char*)arg);

    fd1 = open("log.txt",O_APPEND|O_WRONLY);
    printf("buf = %s ",buf);
    write(fd1,buf,strlen(buf));
    close(fd1);

    // sem_post(&sem);              //释放生产资源
    }

    void * writefunc2(void *arg){

    // sem_wait(&sem);   //申请消费资源
    int fd1;
    char buf[32];
    strcpy(buf,(char*)arg);

    fd1 = open("log.txt",O_APPEND|O_WRONLY);
    printf("buf = %s ",buf);
    write(fd1,buf,strlen(buf));
    close(fd1);

    }

    int main(int argc, const char *argv[])
    {


    int re1,re2;
    pthread_t tid1,tid2;
    char *buf1 = "hello world ";
    char *buf2 = "how are you ";
    int fd;

    // sem_init(&sem,0,0);                //初始化生产队列

    fd = open("log.txt", O_CREAT|O_TRUNC,0777);
    if(fd<0){
    perror("open");
    return -1;
    }
    close(fd);

    re1 = pthread_create(&tid1, NULL,writefunc1,(void*)buf1);
    if(re1){
    printf("pthread_create 1:%s ",strerror(re1));
    return -1;
    }
    pthread_detach(tid1);

    re2 = pthread_create(&tid1, NULL,writefunc2,(void*)buf2);
    if(re2){
    printf("pthread_create 1:%s ",strerror(re2));
    return -1;
    }
    pthread_detach(tid2);

    sleep(10);
    return 0;
    }

  • 相关阅读:
    宣布降低Windows Azure 存储和计算的价格
    物联网操作系统的概念和特点
    基于Windows8与Visual Studio11开发第一个内核驱动程序
    在 C++ 中使用 PPL 进行异步编程
    现实世界的Windows Azure:采访Figlo的全球合作伙伴支持经理Nathan Brouwer
    物联网操作系统随笔
    Windows Azure Toolkit for Windows 8 Consumer Preview的升级版发布了
    上海招聘会场所
    理解 Delphi 的类(十) 深入方法[3] 调用时参数分割
    关于类的入门例子(7): 遍历窗体的所有父类
  • 原文地址:https://www.cnblogs.com/huiji12321/p/11319002.html
Copyright © 2020-2023  润新知