Transplantation of mutex locks and synchronization in Linux (1)

Source: Internet
Author: User

After talking about the basics of multithreading, let's talk about some of my experiences on porting. Porting win32 program multi-thread content to Linux cannot be simply transplanted according to function correspondence. However, through the following ing, coupled with your in-depth understanding of these models, I believe it will be very successful.SemaphoresWindows semaphores are counter variables that allow limited threads/processes to access shared resources. Linux POSIX semaphores are also counter variables that can be used to implement semaphores on Windows in Linux.

  • Semaphore type:Windows provides the famous named) semaphores and the unknown unnamed semaphores. A famous semaphore can be synchronized between processes. In Linux, only POSIX semaphores are used between different threads of the same process. System V semaphores can be used between processes.
  • Wait for the timeout in the function:When used in a waiting function, you can specify a timeout value for the Windows semaphore object. In Linux, this function is not provided, and timeout issues can only be handled through application logic.
Create semaphoresIn Windows, you can use CreateSemaphore()Create or open a famous or unknown semaphore.
HANDLE CreateSemaphore(  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,  LONG lInitialCount,  LONG lMaximumCount,  LPCTSTR lpName);
In this Code:
  • lpSemaphoreAttributesIs a pointer to the security attribute. If the pointer is null, the semaphore cannot be inherited.
  • lInitialCountIs the initial value of the semaphore.
  • lMaximumCountIs the maximum value of the semaphore. The value must be greater than 0.
  • lpNameIs the name of the semaphore. If the value is NULL, the semaphore can only be shared among different threads of the same process. Otherwise, they can be shared between different processes.
This function creates a semaphore and returns the handle of the semaphore. It also sets the initial value to the value specified in the call. This allows a limited number of threads to access a shared resource. In Linux, you can use sem_init()Create an unknown POSIX semaphore, which can be used between threads of the same process. It also initializes the semaphore counter: int sem_init(sem_t *sem, int pshared, unsigned int value). In this Code:
  • valueIs the initial value of the semaphore.
  • psharedIgnore this because POSIX semaphores cannot be shared among processes in the current implementation.
The maximum value is based on the SEM_VALUE_MAX defined in the demaphore. h header file. In Linux, semget()Used to create a System V semaphore, which can be used between different integrated threads. It can be used to implement the same functions as the famous semaphores in Windows. This function returns a semaphore set identifier, which is associated with the key value of a parameter. When you create a new semaphore set semid_dsSemaphores associated with data structures, semget()Initialize them as follows:
  • sem_perm.cuidAndsem_perm.uidIt is set as the valid user ID of the calling process.
  • sem_perm.cgidAndsem_perm.gidIs set as the valid group ID of the calling process.
  • sem_perm.modeIs setsemflg9 bits.
  • sem_nsemsSetnsems.
  • sem_otimeSet to 0.
  • sem_ctimeIs set to the current time.
The code used to create a System V semaphore is: int semget(key_t key, int nsems, int semflg). The following are some explanations of this Code:
  • keyIs a unique identifier. Different processes use it to identify this semaphore set. We can useftok()Generate a unique key value.IPC_PRIVATEIs a specialkey_tValue.IPC_PRIVATEAskeyThis system will only usesemflgBut ignore other content, so that a new semaphore set is created successfully ).
  • nsemsIs the number of semaphores in this semaphores set.
  • semflgIs the permission of the new semaphore set. To create a semaphore set, you can useIPC_CREATTo set bitwise operations or access permissions. If a semaphore set with this key already existsIPC_CREAT/IPC_EXCLThe tag will fail.
Note: In the System V semaphore, keyUsed to uniquely identify the semaphores. In Windows, semaphores are identified by a name. To initialize the data structure of the semaphore set, you can use IPC_SETCommand to call semctl()System Call. Write the values of some members of the semid_ds Data Structure pointed to by arg. buf to the data structure of the semaphore set, and update the value of sem_ctime member of this structure. The user-provided arg. buf points to the semid_ds structure as follows:
  • sem_perm.uid
  • sem_perm.gid
  • sem_perm.modeValid at least 9 characters)
The valid user ID of the calling process should be a superuser, or at least match with the creator or owner of the semaphore set: int semctl(int semid, int semnum, int cmd = IPC_SET, ...). In this Code:
  • semidIs the identifier of the semaphore set.
  • semnumIs the offset of the semaphore subset from 0nsems-1, where n is the number of subsets in the semaphore set ). This command is ignored.
  • cmdIs a command; it usesIPC_SETTo set the semaphore value.
  • argsIn the data structure of this semaphore setIPC_SETThe value to be updated will be explained in this example ).
The maximum counter value is defined according to SEMVMX. Enable semaphoresIn Windows, we use OpenSemaphore()To open a specified semaphore. Semaphores are used only when two processes share semaphores. After the semaphore is successfully opened, the function returns the handle of the semaphore so that it can be used in subsequent calls.
HANDLE OpenSemaphore(  DWORD dwDesiredAccess,  BOOL bInheritHandle,  LPCTSTR lpName)
In this Code:
  • dwDesiredAccessIs the access permission requested by the semaphore object.
  • bInheritHandleIs a flag used to control whether the semaphore handle can inherit. If the value is TRUE, the handle can be inherited.
  • lpNameIs the name of the semaphore.
In Linux, you can call the same semget()To open a semaphore. However semflgThe value is 0: int semget(key,nsems,0). In this Code:
  • keyIt should point to the key value of the semaphore set to be opened.
  • To open an existing semaphore, you cannsemsAnd the flag is set to 0.semflgThe value is set when the access permission is verified before the semaphore set identifier is returned.
Obtain semaphoresIn Windows, the wait function provides a mechanism for obtaining synchronization objects. There are multiple types of available wait functions. In this section, we only consider WaitForSingleObject()Other types will be discussed separately ). This function uses the handle of a semaphore object as a parameter and waits until its status changes to a signal state or times out. DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); In this Code:
  • hHandleIs a pointer to a mutex handle.
  • dwMillisecondsIs the timeout time, in milliseconds. If the value isINFINITEThe time it blocks the calling thread/process is uncertain.
In Linux, sem_wait()Used to obtain access to semaphores. This function suspends the calling thread until the semaphore has a non-empty count. Then, it can reduce the value of this semaphore counter atomically: int sem_wait(sem_t * sem). There is no timeout operation in POSIX semaphores. This can be done by executing a non-blocking sem_trywait()This function calculates the timeout value: int sem_trywait(sem_t * sem). When the System V semaphore is used IPC_SETCommand semctl()You must use semop()To obtain the semaphore. semop()Execute the specified operation in the operation set and block the calling thread/process until the signal value is 0 or greater: int semop(int semid, struct sembuf *sops, unsigned nsops). Function semop()Run sopsOperations included in -- that is, these operations will be executed at the same time only when these operations can be successfully executed at the same time. sopsEach nsopsUse all elements struct sembufSpecifies an operation to be performed on the semaphore. This structure includes the following members:
  • unsigned short sem_num;Number of semaphores)
  • short sem_op;Semaphore Operation)
  • short sem_flg;Operation tag)
To obtain the semaphore, you can sem_opSet to-1 to call semop()After using the semaphore, you can sem_opSet to 1 to call semop()Release semaphores. By adding sem_opSet to-1 to call semop(), The semaphore counter will be reduced by 1. If the value is smaller than 0, the semaphore value cannot be smaller than 0), then the semaphore cannot be reduced, but the calling thread/process will be blocked, until its status changes to a signal state. sem_flgWhich of the following can be recognized? IPC_NOWAITAnd SEM_UNDO. If an operation is set SEM_UNDOWhen the process ends, the operation is canceled. If sem_opSet to 0, then semop()Will wait semvalTo 0. This is an operation that "waits for 0" and can be used to obtain the semaphore. Remember, the timeout operation is not applicable to System V semaphores. This allows you to use non-blocking semop()By adding sem_flgSet IPC_NOWAIT) To calculate the timeout value. Release semaphoresIn Windows, ReleaseSemaphore()Used to release semaphores.
BOOL ReleaseSemaphore(  HANDLE hSemaphore,  LONG lReleaseCount,  LPLONG lpPreviousCount);
In this Code:
  • hSemaphoreIs a pointer to the semaphore handle.
  • lReleaseCountIs a semaphore counter. You can increase the count by specifying the number.
  • lpPreviousCountIs the pointer to the variable returned by the previous semaphore counter. If the value of the previous semaphore counter is not requested, this parameter can be NULL.
This function will increase the semaphore counter value in lReleaseCountAnd then set the semaphore state to a signal state. In Linux, we use sem_post()To release semaphores. This will wake up all threads blocking the semaphore. The semaphore counter is increased by 1 at the same time. You can use a mutex variable to call the following function multiple times to add a specified value to the counter of this semaphore, just like on Windows: int sem_post(sem_t * sem). For System V semaphores, only semop()To release semaphores: int semop(int semid, struct sembuf *sops, unsigned nsops). Function semop()Atomic execution sopsOnly when all operations can be successfully executed at the same time can all operations be completed at the same time ). sopsEach nsopsEach element uses struct sembufThe structure specifies an operation to be performed on the semaphore. The structure contains the following elements:
  • unsigned short sem_num;Number of semaphores)
  • short sem_op;Semaphore Operation)
  • short sem_flg;Operation tag)
To release the semaphore, you can sem_opSet to 1 to call semop(). By adding semop()Set to 1 to call semop(), The counter of this semaphore will increase by 1, and the semaphore will be notified by the signal. Disable/destroy semaphoresIn Windows, we use CloseHandle()To close or destroy the semaphore object.
BOOL CloseHandle(  HANDLE hObject);
hObjectIs a pointer to the synchronization object handle. In Linux, sem_destroy()Destroys the semaphore object and releases its resources: int sem_destroy(sem_t *sem). For System V semaphores, only semctl()Function IPC_RMIDCommand to close the semaphore set: int semctl(int semid, int semnum, int cmd = IPC_RMID, ...). This command will immediately delete the semaphore set and its data structure, wake up all pending processes if an error occurs, then return and errnoSet EIDRM). The valid user ID of the calling process must be a superuser, or a user that can match the creator or owner of the semaphore set. Parameters semnumWill be ignored.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.