1. 程式人生 > 其它 >Linux系統程式設計(七)執行緒控制

Linux系統程式設計(七)執行緒控制

1、執行緒控制

a. pthread_self

獲取執行緒ID

b. pthread_create

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

pthread_attr_t意為執行緒屬性,比如執行緒優先順序等,pthread_create執行成功返回0

#include <stdio.h>
#include <stdlib.h>
#include 
<pthread.h> #include <unistd.h> void* func(void* arg) { printf("thread: pid = %d, tid = %ld\n", getpid(), pthread_self()); return NULL; } int main(int argc, char** argv) { printf("main: pid = %d, tid = %ld\n", getpid(), pthread_self()); pthread_t tid; int ret = pthread_create(&tid, NULL, func, NULL);
if(ret != 0) { perror("pthread_create fail"); exit(1); } sleep(1); return 0; }

man page時看到pthread_create編譯時要加上-pthread,所以編譯時用

$ gcc pthread.c -phread -o pthread

迴圈建立多個執行緒時可能出現問題,例子如下:

void* func(void* arg)
{
    printf("thread %d: pid = %d, tid = %ld\n", *(int*)arg,getpid(), pthread_self());
    
return NULL; } int main(int argc, char** argv) { printf("main: pid = %d, tid = %ld\n", getpid(), pthread_self()); pthread_t tid; int i; for(i = 0; i < 5; i++) { int ret = pthread_create(&tid, NULL, func, (void*)&i); // 這步會出現問題! if(ret != 0) { perror("pthread_create fail"); exit(1); } } sleep(5); return 0; }

看到執行結果如下:

main: pid = 21374, tid = 139621297563456
thread 1: pid = 21374, tid = 139621289035520
thread 2: pid = 21374, tid = 139621280642816
thread 5: pid = 21374, tid = 139621255464704
thread 5: pid = 21374, tid = 139621263857408
thread 5: pid = 21374, tid = 139621272250112

傳遞的是i的地址,子執行緒在執行過程中i值發生變化,子執行緒拿到的值就不是想要的值了

c. pthread_exit

退出當前執行緒

void pthread_exit(void *retval);

這裡來看三個返回:

a. return : 返回到呼叫者

b. pthread_exit :退出執行緒,如果將main函式的return拿掉,新增pthread_exit,那麼主執行緒退出,子執行緒依舊在執行

c. exit :退出程序

d. pthread_join

阻塞等待並回收執行緒

int pthread_join(pthread_t thread, void **retval);
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

struct Thrd_ret{
    int n;
    char str[128];
};

void* func(void* arg)
{
    struct Thrd_ret* ret;
    ret = malloc(sizeof(struct Thrd_ret));
    ret->n = 100;
    strcpy(ret->str, "Hello Thread");
    printf("Thread : pid = %d, tid = %ld\n", getpid(), pthread_self());
    return (void*)ret;
}

int main(int argc, char** argv)
{
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, func, NULL);
    if(ret != 0)
    {
        fprintf(stderr, "pthread_create fail, error = %s\n", strerror(ret));
        exit(1);
    }
    struct Thrd_ret* thrd_ret;
    pthread_join(tid, (void*)&thrd_ret);
    printf("ret->n = %d, ret->str = %s\n", thrd_ret->n, thrd_ret->str);

    pthread_exit(NULL);
}

e. pthread_cancel

殺死執行緒,需要一個取消點,如果沒有取消點,可以通過pthread_testcancel新增取消點

int pthread_cancel(pthread_t thread);

f. pthread_detach

實現執行緒分離,執行緒結束時不會殘留資源在核心當中,分離出去的執行緒執行結束之後自動回收,不需要pthread_join去回收

 

2、執行緒屬性

pthread_attr_int

執行緒屬性初始化

pthread_attr_setdetachstate

設定執行緒屬性為分離屬性

pthread_attr_destroy

銷燬執行緒屬性佔用資源

 

3、執行緒同步