使用信号量进行线程间同步
2009-06-09 15:39
357 查看
转载地址http://hellobmw.com/archives/semaphore-examples-for-windows-and-unix.html
Windows 平台信号量(Semaphore)
#include <stdio.h> #include <Windows.h> #define MAX_SEM_COUNT 10 #define THREADCOUNT 12 HANDLE ghSemaphore; DWORD WINAPI ThreadProc( LPVOID ); void main(int argc, char* argv[]) { HANDLE aThread[THREADCOUNT]; DWORD ThreadID; int i; // Create a semaphore with initial and max counts of MAX_SEM_COUNT ghSemaphore = CreateSemaphore( NULL, // default security attributes - lpSemaphoreAttributes是信号量的安全属性 MAX_SEM_COUNT, // initial count - lInitialCount是初始化的信号量 MAX_SEM_COUNT, // maximum count - lMaximumCount是允许信号量增加到最大值 NULL); // unnamed semaphore - lpName是信号量的名称 if (ghSemaphore == NULL) { printf("CreateSemaphore error: %d/n", GetLastError()); return; } // Create worker threads for( i=0; i <THREADCOUNT; i++ ) { aThread[i] = CreateThread( NULL, // default security attributes 0, // default stack size (LPTHREAD_START_ROUTINE) ThreadProc, NULL, // no thread function arguments 0, // default creation flags &ThreadID); // receive thread identifier if( aThread[i] == NULL ) { printf("CreateThread error: %d/n", GetLastError()); return; } } // Wait for all threads to terminate WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE); // Close thread and semaphore handles for( i=0; i <THREADCOUNT; i++ ) CloseHandle(aThread[i]); CloseHandle(ghSemaphore); } DWORD WINAPI ThreadProc( LPVOID lpParam ) { DWORD dwWaitResult; BOOL bContinue=TRUE; while(bContinue) { // Try to enter the semaphore gate. dwWaitResult = WaitForSingleObject( ghSemaphore, // handle to semaphore 0L); // zero-second time-out interval switch (dwWaitResult) { // The semaphore object was signaled. case WAIT_OBJECT_0: // TODO: Perform task printf("Thread %d: wait succeeded/n", GetCurrentThreadId()); // Ensure a thread performs only once bContinue=FALSE; // Simulate thread spending time on task Sleep(5); // Release the semaphore when task is finished if (!ReleaseSemaphore( ghSemaphore, // handle to semaphore - hSemaphore是要增加的信号量句柄 1, // increase count by one - lReleaseCount是增加的计数 NULL) ) // not interested in previous count - lpPreviousCount是增加前的数值返回 { printf("ReleaseSemaphore error: %d/n", GetLastError()); } break; // The semaphore was nonsignaled, so a time-out occurred. case WAIT_TIMEOUT: printf("Thread %d: wait timed out/n", GetCurrentThreadId()); break; } } return TRUE; }
Unix 平台信号量(Semaphore)
/* semabinit.c - initialize a semaphore for use by programs sema and semb */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> /* The semaphore key is an arbitrary long integer which serves as an external identifier by which the semaphore is known to any program that wishes to use it. */ #define KEY (1492) void main() { int id; /* Number by which the semaphore is known within a program */ /* The next thing is an argument to the semctl() function. Semctl() does various things to the semaphore depending on which arguments are passed. We will use it to make sure that the value of the semaphore is initially 0. */ union semun { int val; struct semid_ds *buf; ushort * array; } argument; argument.val = 0; /* Create the semaphore with external key KEY if it doesn't already exists. Give permissions to the world. */ id = semget(KEY, 1, 0666 | IPC_CREAT); /* Always check system returns. */ if(id <0) { fprintf(stderr, "Unable to obtain semaphore. "); exit(0); } /* What we actually get is an array of semaphores. The second argument to semget() was the array dimension - in our case 1. */ /* Set the value of the number 0 semaphore in semaphore array # id to the value 0. */ if( semctl(id, 0, SETVAL, argument) <0) { fprintf( stderr, "Cannot set semaphore value. "); } else { fprintf(stderr, "Semaphore %d initialized. ", KEY); } }
/* Semaphore example program a (sema.c) */ /* We have two programs, sema and semb. Semb may be initiated at any time, but will be forced to wait until sema is executed. Sema and semb do not have to be executed by the same user! */ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define KEY (1492) /* This is the external name by which the semaphore is known to any program that wishes to Access it. */ void main() { int id; /* Internal identifier of the semaphore. */ struct sembuf operations[1]; /* An "array" of one operation to perform on the semaphore. */ int retval; /* Return value from semop() */ /* Get the index for the semaphore with external name KEY. */ id = semget(KEY, 1, 0666); if(id <0) /* Semaphore does not exist. */ { fprintf(stderr, "Program sema cannot find semaphore, exiting. "); exit(0); } /* Do a semaphore V-operation. */ printf("Program sema about to do a V-operation. "); /* Set up the sembuf structure. */ /* Which semaphore in the semaphore array : */ operations[0].sem_num = 0; /* Which operation? Add 1 to semaphore value : */ operations[0].sem_op = 1; /* Set the flag so we will wait : */ operations[0].sem_flg = 0; /* So do the operation! */ retval = semop(id, operations, 1); if(retval == 0) { printf("Successful V-operation by program sema. "); } else { printf("sema: V-operation did not succeed. "); perror("REASON"); } } /* Think carefully about what the V-operation does. If sema is executed twice, then semb can execute twice. */
/* Semaphore example program b (semb.c) */ /* We have two programs, sema and semb. Semb may be initiated at any time, but will be forced to wait until sema is executed. Sema and semb do not have to be executed by the same user! */ /* HOW TO TEST: Execute semb & The & is important - otherwise you would have have to move to a different terminal to execute sema. Then execute sema. */ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define KEY (1492) /* This is the external name by which the semaphore is known to any program that wishes to access it. */ void main() { int id; /* Internal identifier of the semaphore. */ struct sembuf operations[1]; /* An "array" of one operation to perform on the semaphore. */ int retval; /* Return value from semop() */ /* Get the index for the semaphore with external name KEY. */ id = semget(KEY, 1, 0666); if(id <0) /* Semaphore does not exist. */ { fprintf(stderr, "Program semb cannot find semaphore, exiting. "); exit(0); } /* Do a semaphore P-operation. */ printf("Program semb about to do a P-operation. "); printf("Process id is %d ", getpid()); /* Set up the sembuf structure. */ /* Which semaphore in the semaphore array : */ operations[0].sem_num = 0; /* Which operation? Subtract 1 from semaphore value : */ operations[0].sem_op = -1; /* Set the flag so we will wait : */ operations[0].sem_flg = 0; /* So do the operation! */ retval = semop(id, operations, 1); if(retval == 0) { printf("Successful P-operation by program semb. "); printf("Process id is %d ", getpid()); } else { printf("semb: P-operation did not succeed. "); } } /* Think carefully about what the V-operation does. If sema is executed twice, then semb can execute twice. */
相关文章推荐
- [多线程]使用信号量进行同步
- Linux多线程——使用信号量同步线程
- 进程间通信(IPC)4 ------ 共享内存(配合使用信号量进行同步)
- QT之使用QSemaphore信号量同步线程小例子
- 一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与相互排斥一)
- Linux多线程——使用信号量同步线程
- pthread库学习(2): 线程的同步,使用信号量
- Linux多线程——使用信号量同步线程
- 【多线程】使用信号量进行同步【转】
- linux进程间的通信(C): 使用信号量进行同步的共享内存机制
- 使用信号量实现线程间同步
- 网络编程(40)—— 使用信号量semaphore进行多进程间的同步
- pthread库学习(2): 线程的同步,使用信号量
- Linux多线程——使用信号量同步线程
- 基于visual c++之windows核心编程代码分析(12)使用信号量同步线程
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- Linux多线程——使用信号量同步线程
- linux 线程的同步 三 (内存信号量的使用)
- Linux多线程——使用信号量同步线程
- Linux多线程——使用信号量同步线程