Linux 進程與線程(加鎖--解鎖)


Linux 進程與線程四(加鎖--解鎖)

線程共享進程的內存空間,打開的文件描述符,全局變量。
當有多個線程同事訪問一塊內存空間或者一個變量、一個文件描述符,如果不加控制,那么可能會出現意想不到的結果。
原子操作
對於我們的高級語言(C語言,java,c#),普通的一句代碼一般都是由多條匯編語句組成,計算機CPU每次所執行的都是一條匯編指令
,一條匯編指令是無法再次拆分的,所以計算機CPU同一時間只能執行一條匯編指令就是一個原子操作。
復制代碼
互斥(mutex)是相互排斥的意思,它是一種鎖或者信號燈。
互斥用來保護多個線程共享的數據和結構不會被同事修改,一個互斥鎖只能有兩個狀態
--locked    加鎖
--unlocked    解鎖
加鎖后互斥不讓其他線程訪問。
任何時刻只能有一個線程來掌握某個互斥上鎖。
鎖操作是一個原子操作
一個線程如果試圖在一個已經加鎖的互斥上再加鎖,這個線程會被掛起,,直到加鎖的線程釋放掉互斥鎖為止。
強調:加鎖解鎖針對的是pthread_mutex_t類型的變量,只要有一個地方加鎖,哪怕在別的線程中有加鎖代碼,那個線程也會被掛起,
只有當pthread_mutex_t類型的變量解鎖后,其他的線程才可以繼續對pthread_mutex_t類型的變量加鎖。 注意:互斥情況下,如果將某個正在加鎖占用資源的進程用pthread_cancel函數取消掉,可能產生死鎖。

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
PTHREAD_MUTEX_INITIALIZER是初始化一個快速鎖的宏定義。
pthread_mutex_lock用戶給mutex加鎖。
pthread_mutex_unlock用於給mutex解鎖

復制代碼
復制代碼
//線程加鎖--pthread_mutex_lock
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

//定義一個全局的互斥變量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;

void * MyFunc(void * arg)
{
    if (arg == NULL)
    {
        printf("param is not allow NULL!\n");
        return NULL;
    }
    //加鎖--所有線程都能訪問的全局變量加鎖
    pthread_mutex_lock(&mutex);
    int * pnumx = (int *) arg;
    int i = 0;
    while (i < 10)
    {
        printf("thread%d count=%d\n", *pnumx, count++);
        sleep(1);
        i++;
    }
    //解鎖
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void * MyFunc2(void * arg)
{
    if (arg == NULL)
    {
        printf("param is not allow NULL!\n");
        return NULL;
    }
    //這個鎖和myfunc中的鎖是同一個鎖,myfunc被鎖,這里也會被鎖
    pthread_mutex_lock(&mutex);
    int * pnumx = (int *) arg;
    int i = 0;
    while (i < 10)
    {
        printf("thread%d count=%d\n", *pnumx, count++);
        sleep(1);
        i++;
    }
    //解鎖
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main(int arg, char * args[])
{
    pthread_t thr1, thr2;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    //設置進程為可分離狀態
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    int a = 1, b = 2;
    //創建線程
    if (pthread_create(&thr1, &attr, MyFunc, &a) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    //釋放進程屬性對象
    pthread_attr_destroy(&attr);
    if (pthread_create(&thr2, NULL, MyFunc, &b) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    pthread_join(thr2, NULL);
    printf("main end\n");
    return 0;
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM