线程同步之MUTEX

You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes. Each thread must wait for ownership of the mutex before it can execute the code that accesses the shared resource. For example, if several threads share access to a database, the threads can use a mutex object to permit only one thread at a time to write to the database.

The following example (comes from MSDN)uses the CreateMutex function to create a mutex object and the CreateThread function to create worker threads.

#include 
   
   
    
    
#include 
    
    
     
     

#define THREADCOUNT 2

HANDLE ghMutex;
DWORD WINAPI WriteToDatabase( LPVOID );

int main( void )
{
    HANDLE aThread[THREADCOUNT];
    DWORD ThreadID;
    int i;

    // Create a mutex with no initial owner
    ghMutex = CreateMutex(
        NULL,              // default security attributes
        FALSE,             // initially not owned
        NULL);             // unnamed mutex

    if (ghMutex == NULL)
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }

    // Create worker threads
    for( i=0; i < THREADCOUNT; i++ )
    {
        aThread[i] = CreateThread(
                     NULL,       // default security attributes
                     0,          // default stack size
                     (LPTHREAD_START_ROUTINE) WriteToDatabase,
                     NULL,       // no thread function arguments
                     0,          // default creation flags
                     &ThreadID); // receive thread identifier

        if( aThread[i] == NULL )
        {
            printf("CreateThread error: %d\n", GetLastError());
            return 1;
        }
    }

    // Wait for all threads to terminate
    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    // Close thread and mutex handles
    for( i=0; i < THREADCOUNT; i++ )
        CloseHandle(aThread[i]);
    CloseHandle(ghMutex);
    return 0;
}

DWORD WINAPI WriteToDatabase( LPVOID lpParam )
{
    // lpParam not used in this example
    UNREFERENCED_PARAMETER(lpParam);

    DWORD dwCount=0, dwWaitResult;

    // Request ownership of mutex.
    while( dwCount < 5 )
    {
        dwWaitResult = WaitForSingleObject(
            ghMutex,    // handle to mutex
            INFINITE);  // no time-out interval

        switch (dwWaitResult)
        {
            // The thread got ownership of the mutex
            case WAIT_OBJECT_0:
            {
                    // TODO: Write to the database
                    printf("Thread %d writing to database...\n",
                            GetCurrentThreadId());
                    dwCount++;
                    // Release ownership of the mutex object
                    if (! ReleaseMutex(ghMutex))
                    {
                        // Handle error.
                    }

                break;
            }
            // The thread got ownership of an abandoned mutex
            // The database is in an indeterminate state
            case WAIT_ABANDONED:
                return FALSE;
        }
    }
    return TRUE;
}
/*Thread 7624 writing to database...
Thread 9992 writing to database...
Thread 7624 writing to database...
Thread 9992 writing to database...
Thread 7624 writing to database...
Thread 9992 writing to database...
Thread 7624 writing to database...
Thread 9992 writing to database...
Thread 7624 writing to database...
Thread 9992 writing to database...

Process returned 0 (0x0)   execution time : 0.251 s
Press any key to continue.
*/

    
    
   
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux 中线程同步的方式有很多,以下是其中一些常见的: 1. 互斥锁(Mutex):用于保护共享资源,只允许一个线程访问共享资源。当一个线程获取到互斥锁后,其他线程就必须等待这个线程释放锁后才能获取锁。 2. 读写锁(Reader-Writer Lock):在读多写少的情况下,使用读写锁可以提高并发性能。读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。 3. 条件变量(Condition Variable):用于等待某个条件满足时才执行。当一个线程等待某个条件变量时,它会被阻塞,直到另外一个线程发出信号,通知条件已经满足,该线程才会继续执行。 4. 信号量(Semaphore):用于控制同时访问共享资源的线程数量。信号量可以是计数信号量或二进制信号量。计数信号量可以用来控制多个线程同时访问一个资源的数量,而二进制信号量只允许一个线程访问资源。 5. 屏障(Barrier):用于让多个线程在某个点上同步执行。当多个线程执行到某个点时,它们会被阻塞,直到所有线程都到达该点,才会继续执行。 这些同步机制可以根据具体的场景选择使用。在实际开发中,需要考虑多线程的安全性、性能等因素,选择合适的同步机制来实现线程同步。 ### 回答2: 在Linux中,线程同步是指多个线程之间的操作需要协调,以确保它们在执行任务时能够按照预期的顺序进行。 线程同步的目的是确保多个线程共享的资源(如共享内存、文件、网络连接等)能够被有序地访问和操作,避免出现竞态条件和资源争夺等问题,确保程序的正确性和性能。 常见的线程同步机制包括互斥锁、条件变量、读写锁、信号量等。 互斥锁是最基本的一种线程同步机制,它可以确保在任何时候只有一个线程可以访问共享资源。当某个线程获取了互斥锁之后,其他线程必须等待该线程释放锁后才能继续执行。互斥锁通过使用标志位和原子操作来确保线程的互斥性。 条件变量是一种线程同步机制,它可以使线程在满足某些条件之前一直等待,从而避免忙等待和浪费资源。条件变量常与互斥锁一起使用,当共享资源不满足条件时,线程可以使用条件变量进入等待状态,直到该条件被满足,另一个线程发出信号来唤醒等待线程。 读写锁是一种用于多线程读写共享资源的机制,它允许多个线程同时进行读操作,但只允许一个线程进行写操作。读写锁可以提高程序的并发性能,但需要注意避免读-写之间的竞争条件。 信号量是一种基于计数器的线程同步机制,它可以控制共享资源的访问数量和顺序。信号量可以实现互斥锁、条件变量等多种功能,是一种比较通用的线程同步机制。 除了上述机制,Linux中还有其他一些线程同步工具和算法,如屏障、自旋锁、分段锁、标记等。不同的线程同步机制和算法适用于不同的场景和需求,需要根据具体情况进行选择和使用。 ### 回答3: 在Linux中,由于多线程同时访问共享资源可能导致竞争条件的出现,因此需要使用线程同步技术来避免这种情况。除了使用互斥锁和条件变量来实现线程同步之外,也可以使用Linux提供的信号量机制。 信号量是一个整数值,用于控制对共享资源的访问。它包括两个主要的操作:PV操作和初始化操作。PV操作分为两种:P操作(等待操作)和V操作(释放操作)。一个线程在访问共享资源之前,必须执行P操作,如果信号量的值为0,则该线程将被阻塞。当线程使用完共享资源后,必须执行V操作来释放信号量,并唤醒其他等待访问共享资源的线程。 在Linux中使用信号量需要包含头文件<sys/sem.h>,并使用semget函数创建一个新的信号量集。接着,使用semctl函数可对信号量进行初始化或者删除操作。使用semop函数可进行PV操作。 与互斥锁和条件变量相比,信号量机制的优点是可以在不同进程间进行线程同步,而且可以实现多个线程同时访问共享资源的问题。但是,使用信号量需要特别小心,因为它比互斥锁和条件变量更难调试,如果使用不当会导致死锁等问题。 总之,Linux提供了多种线程同步机制,开发人员需要根据实际需求选择合适的机制来避免竞争条件的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值