Thread

Introduction to pThread

  • pThread 頭文件:pthread.h
  • Functions:
  1. pthread_mutex_unlock: 解除鎖定mutex所指向的互斥鎖的函數(shù)
  2. pthread_mutex_lock: 鎖定互斥鎖
  3. pthread_mutex_t: creat a mutex in pthread
  4. pthread_join: join with a terminated thread
  5. pthread_create: 創(chuàng)建thread
    pthread_create(pthread_t tidp,const pthread_attr_t attr,(void)(start_rtn)(void*),void *arg);
    arguments: 線程id工闺,線程屬性(就NULL吧),線程運(yùn)行函數(shù)地址瓣蛀,運(yùn)行函數(shù)參數(shù)
  6. pthread_t: 定義thread id
  7. pthread_setaffinity_np: set the CPU affinity mask of a thread to the pointed CPU or CPUs
  8. pthread_getaffinity_np: return the CPU affinity mask of the thread in the buffer

Configuration

可以用lscpu顯示CPU configuration

Compile

pthread library已經(jīng)預(yù)裝在ubuntu
舉個(gè)例子:helloworld.c

#include <stdio.h>
#include <pthread.h>

void * hello(void *input) {
    printf("%s\n", (char *)input);
    pthread_exit(NULL);
}

int main(void) {
    pthread_t tid;
    pthread_create(&tid, NULL, hello, "hello world");
    pthread_join(tid, NULL);
    return 0;
}

Compile用

gcc -o helloworld helloworld.c -lpthread
運(yùn)行
./helloworld

Race Condition(競(jìng)爭(zhēng)條件)

source: https://blog.csdn.net/u012562273/article/details/56486776
(Oct 15 2018)

從多進(jìn)程間通信的角度來(lái)講陆蟆,是指兩個(gè)或多個(gè)進(jìn)程對(duì)共享的數(shù)據(jù)進(jìn)行讀或?qū)懙牟僮鲿r(shí),最終的結(jié)果取決于這些進(jìn)程的執(zhí)行順序惋增。(https://baike.baidu.com/item/%E7%AB%9E%E6%80%81%E6%9D%A1%E4%BB%B6/1321097?fr=aladdin)

Race Condition分為兩類

  • Mutex(互斥): 兩個(gè)或多個(gè)進(jìn)程彼此之間沒(méi)有內(nèi)在的制約關(guān)系叠殷,但是由于要搶占使用某個(gè)臨界資源(不能被多個(gè)進(jìn)程同時(shí)使用的資源,如打印機(jī)诈皿,變量)而產(chǎn)生制約關(guān)系
  • Synchonization(同步): 兩個(gè)或多個(gè)進(jìn)程彼此之間存在制約關(guān)系(前一個(gè)進(jìn)程執(zhí)行完林束,其他的進(jìn)程才能執(zhí)行)

Solutions

  • Busy Waiting(忙等待): 等著但是不停的檢查測(cè)試,直到能進(jìn)行為止
  • Sleep and Wakeup(睡眠與喚醒): 引入Semaphore稽亏,喚醒由其他進(jìn)程引發(fā)
    舉個(gè)例子:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NITERS 10000000

void *count (void *arg);

unsigned int cnt = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main () {

    pthread_t tid1, tid2;
    pthread_create (&tid1, NULL, count, NULL);
    pthread_create (&tid2, NULL, count, NULL);

    pthread_join (tid1, NULL);
    pthread_join (tid2, NULL);
    printf ("cnt:%d\n", cnt);
    exit (0);

}

void *count (void *arg) {

    int i = 0;

    for (; i < NITERS; i++) {
        pthread_mutex_lock(&mutex); //mutex
        cnt++;
        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

Deadlock

e.g.
Allen borrows Book1 first, after the borrowes Book1, he starts to find Book2
Bob borrows Book2 first, after he borrowed Book2, he starts to find Book1.
-->Deadlock
Solution:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

void *Allen(void *arg);
void *Bob(void *arg);

pthread_mutex_t book1;
pthread_mutex_t book2;
pthread_cond_t Allenfinish;

int main() {
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, &Allen, NULL);
    pthread_create(&tid2, NULL, &Bob, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

void *Allen(void *arg) {
    pthread_mutex_lock(&book1);
    sleep(5);
    pthread_mutex_lock(&book2);
    printf("Allen has collected all books he need, he is going to do homework!\n");
    sleep(5);
    printf("Allen has finished his homework, he has returned all books he borrowed!\n");
    pthread_mutex_unlock(&book2);
    pthread_mutex_unlock(&book1);
    pthread_cond_signal(&Allenfinish);
}

void *Bob(void *arg) {
    pthread_mutex_lock(&book2);
    pthread_cond_wait(&Allenfinish, &book2);

    printf("Bob knows he can borrow those two books now!\n");
    pthread_mutex_lock(&book1);
    sleep(5);
    printf("Bob has finished his homework now!\n");
    pthread_mutex_unlock(&book1);
    pthread_mutex_unlock(&book2);
}

Passing Arguments

舉個(gè)栗子:

#include <stdio.h>
#include <pthread.h>

void * hello(void *input) {
    printf("%s\n", (char *)input);
    pthread_exit(NULL);
}

int main(void) {
    pthread_t tid;
    pthread_create(&tid, NULL, hello, "hello world");
    pthread_join(tid, NULL);
    return 0;
}

傳遞多個(gè)參數(shù):

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

struct args {
    char* name;
    int age;
};

void *hello(void *input) {
    printf("name: %s\n", ((struct args*)input)->name);
    printf("age: %d\n", ((struct args*)input)->age);
}

int main() {
    struct args *Allen = (struct args *)malloc(sizeof(struct args));
    char allen[] = "Allen";
    Allen->name = allen;
    Allen->age = 20;

    pthread_t tid;
    pthread_create(&tid, NULL, hello, (void *)Allen);
    pthread_join(tid, NULL);
    return 0;
}

Pin a thread to a core

source: https://www.cnblogs.com/wenqiang/p/6049978.html
(Oct 15 2018)

Affinity

CPU的親和性(Affinity)就是將指定的進(jìn)程或線程綁定到相應(yīng)的CPU上

  • 軟親和性:進(jìn)程在指定的CPU上盡量長(zhǎng)時(shí)間地運(yùn)行而不被遷移到其他處理器壶冒。linux內(nèi)核進(jìn)程調(diào)度器具有軟CPU親和性,不會(huì)再處理器之間頻繁遷移截歉,產(chǎn)生的負(fù)載小
  • 硬親和性:利用linux內(nèi)核提供給用戶的API胖腾,強(qiáng)行將進(jìn)程綁定到指定的CPU運(yùn)行

相關(guān)functions

作者:jsdchenye
來(lái)源:CSDN
原文:https://blog.csdn.net/jsdchenye/article/details/44703615?utm_source=copy

  • void CPU_ZERO(cpu_set_t *set);(初始化操作)
  • void CPU_SET(int cpu,cpu_set_t *set)(將某個(gè)cpu加進(jìn)cpu集里)
  • void CPU_CLR(int cpu,cpu_set_t *set)(將某個(gè)cpu清除出cpu集里)
  • void CPU_ISSET(int cpu,const cpu_set_t *set)(判斷某個(gè)cpu是不是在cpu集里)

栗子:

#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

/* print the error message and exit */
#define handle_error_en(en, msg) \
      do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)


int main(int argc, char *argv[])
{
    int s, j;
    int CPUNUM = 4;
    cpu_set_t cpuset;
    pthread_t thread;

    thread = pthread_self(); // get the id of the current thread

    CPU_ZERO(&cpuset);  // empty the cpu set
    for (j = 0; j < CPUNUM - 1; j++)
        CPU_SET(j, &cpuset);  // add each cpu to the cpu set except the cpu 3

    /* Set affinity mask to include CPUs 0 to 2 */
    s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);

    if (s != 0)
        handle_error_en(s, "pthread_setaffinity_np");

    /* Check the actual affinity mask assigned to the thread */
    s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
    if (s != 0)
        handle_error_en(s, "pthread_getaffinity_np");

    printf("Set returned by pthread_getaffinity_np() contained:\n");
    for (j = 0; j < CPUNUM; j++)
        if (CPU_ISSET(j, &cpuset))
            printf("CPU %d is set affinity\n", j);
        else
            printf("CPU %d is not set affinity\n", j);

    exit(EXIT_SUCCESS);
}

兩個(gè)栗子
source: https://www.cnblogs.com/wenqiang/p/6049978.html
(Oct 15 2018)

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

void *testfunc(void *arg)
{
    int i, cpus = 0;
    cpu_set_t mask;
    cpu_set_t get;

    cpus = sysconf(_SC_NPROCESSORS_CONF);
    printf("this system has %d processor(s)\n", cpus);
    
    CPU_ZERO(&mask);
    for (i = 0; i < 4; i++) { /*將0、1瘪松、2咸作、3添加到集合中*/
        CPU_SET(i, &mask);
    }   

    /* 設(shè)置cpu 親和性(affinity)*/
    if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
        fprintf(stderr, "set thread affinity failed\n");
    }   
    
    /* 查看cpu 親和性(affinity)*/
    CPU_ZERO(&get);
    if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
        fprintf(stderr, "get thread affinity failed\n");
    }   

    /* 查看當(dāng)前線程所運(yùn)行的所有cpu*/
    for (i = 0; i < cpus; i++) {
        if (CPU_ISSET(i, &get)) {
            printf("this thread %d is running in processor %d\n", (int)pthread_self(), i); 
        }   
    }   
    sleep(3); //查看
    
    pthread_exit(NULL);
}
 
int main(int argc, char *argv[])
{
    pthread_t tid;
    if (pthread_create(&tid, NULL, (void *)testfunc, NULL) != 0) {
        fprintf(stderr, "thread create failed\n");
        return -1; 
    }   

    pthread_join(tid, NULL);
    return 0;
}

Introduction to OpenMP

Hello, World!

栗子

#include <omp.h>
#include <stdio.h>
main(int argc, char *argv[]) {

    int nthreads, tid;

    /* Fork a team of threads with each thread having a private tid variable */
    #pragma omp parallel private(tid)
    {

        /* Obtain and print thread id */
        tid = omp_get_thread_num();
        printf("Hello World from thread = %d\n", tid);

        /* Only master thread does this */
        if (tid == 0)
        {
            nthreads = omp_get_num_threads();
            printf("Number of threads = %d\n", nthreads);
        }

    }  /* All threads join master thread and terminate */

}

Compile:

gcc -o helloworld helloworld.c -fopenmp

To run:

./heloworld
Hello World from thread = 0
Number of threads = 4
Hello World from thread = 3
Hello World from thread = 2
Hello World from thread = 1

Parallel in OpenMP

#pragma omp parallel private(tid)

compiler directive statement, 寫在parallel region之前

omp_set_num_threads(4):

告訴compiler需要4個(gè)線程

pragma omp parallel for

告訴compiler將for loop并行

Getting faster using OpenMP

//他爸爸的太難了, 看不下去

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宵睦,一起剝皮案震驚了整個(gè)濱河市记罚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壳嚎,老刑警劉巖桐智,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件末早,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酵使,警方通過(guò)查閱死者的電腦和手機(jī)荐吉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門焙糟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)口渔,“玉大人,你說(shuō)我怎么就攤上這事穿撮∪甭觯” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵悦穿,是天一觀的道長(zhǎng)攻礼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)栗柒,這世上最難降的妖魔是什么礁扮? 我笑而不...
    開(kāi)封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮瞬沦,結(jié)果婚禮上太伊,老公的妹妹穿的比我還像新娘。我一直安慰自己逛钻,他們只是感情好僚焦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著曙痘,像睡著了一般芳悲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上边坤,一...
    開(kāi)封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天名扛,我揣著相機(jī)與錄音,去河邊找鬼茧痒。 笑死罢洲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的文黎。 我是一名探鬼主播惹苗,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耸峭!你這毒婦竟也來(lái)了桩蓉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤劳闹,失蹤者是張志新(化名)和其女友劉穎院究,沒(méi)想到半個(gè)月后洽瞬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡业汰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年伙窃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片样漆。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡为障,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出放祟,到底是詐尸還是另有隱情鳍怨,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布跪妥,位于F島的核電站鞋喇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏眉撵。R本人自食惡果不足惜侦香,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纽疟。 院中可真熱鬧罐韩,春花似錦、人聲如沸仰挣。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)膘壶。三九已至错蝴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間颓芭,已是汗流浹背顷锰。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亡问,地道東北人官紫。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像州藕,于是被迫代替她去往敵國(guó)和親束世。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容