📜  Linux 中的同步命令与示例(1)

📅  最后修改于: 2023-12-03 15:32:41.504000             🧑  作者: Mango

Linux 中的同步命令与示例

在编程的过程中,为了确保程序安全可靠地运行,在某些情况下需要使用同步命令。Linux 操作系统提供了多种同步命令,用于控制多个进程之间的资源竞争,避免数据的不一致和冲突。本文将介绍一些常见的同步命令及其示例。

1. Mutex

Mutex(互斥锁)是一种基本的同步机制,用于控制对共享资源的访问。每次只有一个线程可以获得该锁,并执行关键代码部分,其他线程则被阻塞直到锁被释放。

下面是一个使用 Mutex 的 C++ 代码示例:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void thread_func(int id)
{
    mtx.lock();
    std::cout << "Thread " << id << " is executing critical section." << std::endl;
    mtx.unlock();
}

int main()
{
    std::thread t1(thread_func, 1);
    std::thread t2(thread_func, 2);

    t1.join();
    t2.join();

    return 0;
}

在这个示例代码中,我们定义了两个线程 t1 和 t2,并在这两个线程中使用了 Mutex 对关键代码部分进行了保护。

2. Semaphore

Semaphore(信号量)是一种同步机制,用于控制同时访问固定数量资源的多个线程。对于具有限定资源的示例,我们可以使用 Semaphore 来实现资源的共享。

下面是一个使用 Semaphore 的 Python 代码示例:

import time
from threading import Semaphore, Thread

semaphore = Semaphore(2)

def thread_func(n):
    with semaphore:
        print("Thread {} is accessing a shared resource...".format(n))
        time.sleep(3)

for i in range(5):
    t = Thread(target=thread_func, args=(i,))
    t.start()

在这个示例代码中,我们定义了一个 Semaphore,它的初始值为 2。然后我们创建了 5 个线程,并在每个线程中使用了 with 语句来获取该 Semaphore。由于 Semaphore 初始值为 2,因此只有两个线程能同时获得该 Semaphore,其他线程将会被阻塞。

3. Condition

Condition(条件变量)是一种同步机制,用于在不同线程间进行某些通信。当某些数据满足一定条件时,线程可以等待该条件,直到其他线程通知该条件被满足。

下面是一个使用 Condition 的 Java 代码示例:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    private static final Lock lock = new ReentrantLock();
    private static final Condition notEmpty = lock.newCondition();

    private static Queue<String> queue = new LinkedList<>();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                while (queue.isEmpty()) {
                    notEmpty.await();
                }
                System.out.println(queue.poll());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        Thread t2 = new Thread(() -> {
            lock.lock();
            try {
                Thread.sleep(2000);
                queue.add("Hello World!");
                notEmpty.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("Finished.");
    }
}

在该示例中,我们定义了两个线程 t1 和 t2。线程 t1 从队列中读取数据,如果队列为空则等待条件变量 notEmpty 被通知。线程 t2 向队列中添加数据,并通知条件变量 notEmpty。

4. Barrier

Barrier(屏障)是一种同步机制,用于控制多个线程的同步。当多个线程都到达同一个关键点时,才能继续执行后续代码。

下面是一个使用 Barrier 的 C 代码示例:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

pthread_barrier_t barrier;

void* thread_func(void* arg)
{
    int id = *(int*)arg;
    printf("Thread %d arrives at the barrier.\n", id);
    pthread_barrier_wait(&barrier);
    printf("Thread %d passed the barrier.\n", id);

    return NULL;
}

int main(void)
{
    const int num_threads = 5;
    pthread_t threads[num_threads];
    int ids[num_threads];

    pthread_barrier_init(&barrier, NULL, num_threads);

    for (int i = 0; i < num_threads; ++i) {
        ids[i] = i;
        pthread_create(&threads[i], NULL, thread_func, &ids[i]);
    }

    for (int i = 0; i < num_threads; ++i) {
        pthread_join(threads[i], NULL);
    }

    pthread_barrier_destroy(&barrier);
    return 0;
}

在该示例中,我们定义了 5 个线程和一个 Barrier。当一个线程到达该 Barrier 时,它会调用 pthread_barrier_wait 函数等待其他线程。当所有线程都到达该 Barrier 时,它们都会被释放,执行后续代码。

结论

本文介绍了 4 种常见的 Linux 中同步命令及其示例:Mutex、Semaphore、Condition、Barrier。我们可以在程序编写过程中根据需求使用适合的同步命令,确保程序的数据安全和可靠性。