1. 程式人生 > >linux下用信號量同步線程

linux下用信號量同步線程

amp serve 計數 thread roc 統計 ida 線程鎖 linu

linux下利用信號量同步線程實現線程訪問計數功能

這裏是核心代碼,其他參考IPC一個綜合小實踐

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ipc_sem.h"
#include "ipc_shm.h"
#include <pthread.h> int g_key = 0x1234; int doServeice() { //開始使用信號量來創造臨界區 int semid = 0; sem_open(g_key, &semid); sem_p(semid); //臨界區開始 int shmhdl = 0; int ret = shm_creat(".", 0, &shmhdl); if(ret!=0) { return ret; }
int *addr = NULL; ret =shm_map(shmhdl, (void **)&addr); if(ret!=0) { return ret; } // 進程訪問數+1 *((int *)addr) += 1; //統計總共訪問的次數。 int ncount = *((int *)addr); printf("ncount: %d\n", ncount); ret =shm_unmap(addr);
//sleep(1); sem_v(semid); //臨界區開始 } void* thread_routine(void *arg) { int loop = *((int *)arg); for(int i=0; i<loop; ++i) { doServeice(); } pthread_exit(NULL); } int main() { int procnum; printf("輸入創建子線程的個數 : \n"); scanf("%d", &procnum); int loopnum; printf("輸入每個子線程測試多少圈 :\n"); scanf("%d", &loopnum); //共享內存創建 int shmhdl = 0; int ret = shm_creat(".", sizeof(int), &shmhdl); if (ret != 0) { printf("shm_creat() Err.\n"); return ret; } //共享內存創建成功 //信號量的創建 int semid = 0; ret = sem_creat(g_key, &semid); if (ret != 0) { printf("sem_creat() Err. Try Again.\n"); if (errno == EEXIST) { ret = sem_open(g_key, &semid); if (ret != 0) { printf("Failed Again!\n"); return ret; } } else { return ret; } } int val = 0; ret = sem_getval(semid, &val); if (ret != 0 ) { printf("sem_getval() Err.\n"); return ret; } printf("sem val: %d\n", val); //用來阻塞到鍵盤 getchar(); pthread_t tidArray[1024*4]; for (int i=0; i<procnum; i++) { pthread_create(&tidArray[i], NULL, thread_routine, (void*)&loopnum); } for (int i=0; i<procnum; i++) { pthread_join(tidArray[i],NULL); } shm_delete(shmhdl); sem_delete(g_key); return 0; }

線程同步可以使用互斥鎖,也可以使用信號量。互斥鎖是一個線程鎖,只能鎖線程不能鎖進程,信號量既可以同步線程也可以同步進程。線程鎖是定義在進程 之上的。

線程鎖是線程庫提供的一個機制,和信號量不同,信號量是IPC機制,直接歸內核管理。它們兩個級別不一樣。

下面用線程鎖同步線程功能 只要將PV操作換成線程鎖的形式就可以了。

int doServeice()
{
    //開始使用信號量來創造臨界區
    int semid = 0;
    sem_open(g_key, &semid);

    pthread_mutex_lock(&mutex);
     //sem_p(semid); //臨界區開始
        int shmhdl = 0;
        int ret = shm_creat(".", 0, &shmhdl);
        if(ret!=0)
        {
            return ret;
        }
        int *addr = NULL;
        ret =shm_map(shmhdl, (void **)&addr);
        if(ret!=0)
        {
            return ret;
        }
        // 進程訪問數+1
        *((int *)addr) += 1;
        //統計總共訪問的次數。
        int ncount = *((int *)addr);
        printf("ncount: %d\n", ncount);
        ret =shm_unmap(addr);
        //sleep(1);
    //sem_v(semid);  //臨界區開始
    pthread_mutex_unlock(&mutex);
}

就可以很容易的實現上面的功能。

linux下用信號量同步線程