linux下用信號量同步線程
阿新 • • 發佈:2018-06-16
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下用信號量同步線程