線程

線程:進程中的一條執行路徑。
在單CPU系統上,多個線程併發執行。
線程(thread):一個進程可以有多個線程,必須至少有一個線程(即主線程,主函數由主線程執行)
TID:線程ID
(一個程序做多個事情,一個線程相當於一個人肚子裏的一條蛔蟲)
一個進程中的所有線程共享該進程所有資源(空間共享,通信就直接簡單了)。
進程產生後:操作系統會分配PID、私有地址空間
進程沒有執行能力,進程是操作系統分配資源的基本單位。
每個線程都唯一對應一個線程函數,線程創建成功後會自動去調用自己的線程函數,線程函數執行完返回,該線程也就結束了。
進程與線程的區別和聯繫
1. 進程是操作系統分配資源的基本單位,沒有執行能力。線程是操作系統分配CPU時間片的基本單位(調度的基本單元),具有執行能力。
2. 進程間通信很繁瑣,但同一進程中的不同線程間通信很簡單。
3. 線程屬於進程,一個進程可以有多個線程,一個線程只屬於某一個進程

(每次切換線程都要保存其他線程信息(保護現場))
不要創建太多線程,系統中線程太多會嚴重影響系統性能,因爲系統會忙於線程調度處理。並且保存每個線程的現場信息(即當前運行狀態和位置等)會消耗大量內存空間。
主線程和普通線程的區別:
1、 主線程由操作系統親自創建,而普通線程由主線程直接或間接創建
2、 主線程只能有一個,而普通線程可以有多個或沒有
3、 主線程結束進程就結束了,而普通線程結束對其他線程沒有影響
相關函數 //進程編號 //狀態(堆區棧區大小,優先級等)
 創建進程int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void (*start_routine) (void ), void *arg);
//線程函數 //傳給線程的參數
 等待線程結束:int pthread_join(pthread_t thread, void **retval); //不關注時傳NULL
//線程編號//線程結束信息(線程函數的返回值爲void*)
成功返回0,錯誤放回錯誤號(不是-1)
 結束進程:pthread_exit(自殺),pthread_cancel(他殺,不建議這樣操作)
void pthread_exit(void *retval);
//線程結束信息
int pthread_cancel (pthread_t thread); //只是一個請求,可用pthread_setcancelstate設置
用法示例:
 pthread_detach(pthread_self()); 給線程標標記,線程結束後操作系統會釋放其資源。
不用等主線程釋放,自己線程完了之後就可以釋放資源。
創建線程後一定要使用(pthread_join或pthread_detach)釋放資源
一般不建議強制結束線程,而是通過設置全局變量的值來給線程發信號結
束。

線程代碼

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void* thr_fun(void* arg);
int exit_flag=0;//
int main()//主線程與其他線程併發執行
{
    pthread_t tid;
    if(pthread_create(&tid,NULL,thr_fun,NULL)!=0)//創建一個線程
    {                                  
        fprintf(stderr,"pthread_create fail\n");
        exit(-1);
    }
    int a;
    for(a=0;a<5;a++)//主線程結束,其他線程也隨即結束
    {
        printf("hello dj\n");
        sleep(1);
    }
    pthread_join(tid,NULL);//主線程阻塞,進入子線程,直到子線程結束
    return 0;
}
void* thr_fun(void* arg)//線程函數,多個線程時,執行順序不確定
{
    int i;
    for(i=0;i<5;i++)
    {
        printf("你好\n");
        sleep(1);
    }
    pthread_exit((void*)3);//自行結束進程
    return NULL;
}

多線程代碼

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define N 10000
void* thr_fun(void* arg);
int main()//分析思想:一個語句還沒執行完,被打斷,進入另一個線程
{
    int i;
    pthread_t tid[N];
    for(i=0;i<N;i++)//創建N個進程
    {   
        if(pthread_create(&tid[i],NULL,thr_fun,(void*)&i)!=0)//傳地址
//      if(pthread_create(&tid[i],NULL,thr_fun,&i)!=0)//傳地址//容易錯誤
//      if(pthread_create(&tid[i],NULL,thr_fun,(void*)i)!=0)//傳值
            //因爲int和指針都佔四個字節,所以可以強轉,否則截斷  
        {                                    //給線程函數傳參
            fprintf(stderr,"pthread_create\n");//通過參數區分不同線程
            exit(1);
        }
        usleep(1000);//阻塞主進程,以免i值被改變

    }
    for(i=0;i<N;i++)
    {
        pthread_join(tid[i],NULL);//同wait,兩個作用,一是等子進程結束
    }                             //二是釋放線程資源
    return 0;
}
void* thr_fun(void* arg)//多個線程共用一個線程函數
{
    pthread_detach(pthread_self());//pthread_self函數可獲得線程ID
                                   //設置單身
    int p=*(int*)arg;
//  int* p=(int*)arg;//讀主線程中i的值,而主線程一直在該i的值//讀地址值
//  int p=(int)arg;//讀值
    printf("%d號進程\n",p);

    return NULL;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章