C语言提供的线程/进程间同步(锁)机制

本文详细介绍了C语言中线程间同步机制(互斥体、读写锁、条件变量和自旋锁)以及进程间同步机制(信号量、信号、消息队列、共享内存、管道和套接字)。这些技术对于并发编程至关重要,理解它们能提升程序的效率和可靠性。
摘要由CSDN通过智能技术生成

目录

 

一、C语言提供的线程间同步机制

1、互斥体 (Mutex)

2、读写锁(read-write locks)

3、条件变量 (conditional variables)

4、自旋锁(spinlocks)

 

二、C语言提供的进程间同步机制

1、信号量(semaphore)

2、信号SIGNAL

4、消息队列

5、共享内存

6、管道和套接字


一、C语言提供的线程间同步机制


1、互斥体 (Mutex)


描述:互斥体是比信号量更为简单是睡眠锁。
使用范围:最为常用。

#include <pthread.h>

/* Initialize a mutex. */
extern int pthread_mutex_init (pthread_mutex_t *__mutex,
                   const pthread_mutexattr_t *__mutexattr)
     __THROW __nonnull ((1));

/* Destroy a mutex.  */
extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
     __THROW __nonnull ((1));

/* Try locking a mutex.  */
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

/* Lock a mutex.  */
extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

/* Unlock a mutex.  */
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

2、读写锁(read-write locks)

 

描述:一个或者多个读任务可以并发获取读者锁,而用于写的锁最多只能被一个写任务所持有。==感觉是为了优化屏障而生,不确定==
使用范围:仅__USE_UNIX98 或 defined __USE_XOPEN2K8 可用。

 

#include <pthread.h>

extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
                const pthread_rwlockattr_t *__restrict
                __attr) __THROW __nonnull ((1));

/* Destroy read-write lock RWLOCK.  */
extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
     __THROW __nonnull ((1));

/* Acquire read lock for RWLOCK.  */
extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));

/* Acquire write lock for RWLOCK.  */
extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));

/* Unlock RWLOCK.  */
extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));


3、条件变量 (conditional variables)

描        述:主要用来等待某个条件的发生。可以用来同步同一进程中的各个线程。
使用范围:

#include <pthread.h>

extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
                  const pthread_condattr_t *__restrict __cond_attr)
     __THROW __nonnull ((1));

/* Destroy condition variable COND.  */
extern int pthread_cond_destroy (pthread_cond_t *__cond)
     __THROW __nonnull ((1));

/* Wake up one thread waiting for condition variable COND.  */
extern int pthread_cond_signal (pthread_cond_t *__cond)
     __THROWNL __nonnull ((1));

/* Wake up all threads waiting for condition variables COND.  */
extern int pthread_cond_broadcast (pthread_cond_t *__cond)
     __THROWNL __nonnull ((1));

extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
                  pthread_mutex_t *__restrict __mutex)

extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
                   pthread_mutex_t *__restrict __mutex,
                   const struct timespec *__restrict __abstime)


4、自旋锁(spinlocks)


描述:当锁被某个线程占用时,其他线程在获取锁时会一直进行“忙循环-旋转-等待锁”。
使用范围:自旋锁不会休眠,故仅用于保护短的代码段。
API:

#include <pthread.h>

/* Initialize the spinlock LOCK.  If PSHARED is nonzero the spinlock can
   be shared between different processes.  */
extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
     __THROW __nonnull ((1));

/* Destroy the spinlock LOCK.  */
extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
     __THROW __nonnull ((1));

/* Wait until spinlock LOCK is retrieved.  */
extern int pthread_spin_lock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Try to lock spinlock LOCK.  */
extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Release spinlock LOCK.  */
extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

 

二、C语言提供的进程间同步机制


1、信号量(semaphore)

描       述:Linux中的信号量是一种睡眠锁。如果有一个任务企图获取一个不可用(被占用)的信号量时,信号量会被推进一个等待队列,然后让其休眠。
                  当持有的信号量可用(被释放)后,处于等待队列的那个任务才被唤醒,并获得该信号量。
使用范围:由于等待信号量线程会休眠(开销大),所以信号量适用于锁被长时间持有的情况。使用信号量的同时不能占用自旋锁(不允许休眠),否则不能进入休眠。
API:

 #include <semaphore.h>

extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
     __THROW;
/* Free resources associated with semaphore object SEM.  */
extern int sem_destroy (sem_t *__sem) __THROW;

/* Open a named semaphore NAME with open flags OFLAG.  */
extern sem_t *sem_open (const char *__name, int __oflag, ...) __THROW;

/* Close descriptor for named semaphore SEM.  */
extern int sem_close (sem_t *__sem) __THROW;

/* Remove named semaphore NAME.  */
extern int sem_unlink (const char *__name) __THROW;

/* Wait for SEM being posted.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int sem_wait (sem_t *__sem);

/* Post SEM.  */
extern int sem_post (sem_t *__sem) __THROWNL;

2、信号SIGNAL


描        述:信号是一种比较始的通信机制。尽管提供的选项较少,但是它们非常有用。
使用范围:小数据。通常用于捕获系统定义的信号。

#include <signal.h>

/* Change the set of blocked signals to SET,
   wait until a signal arrives, and restore the set of blocked signals.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int sigsuspend (const sigset_t *__set) __nonnull ((1));

/* Get and/or set the action for signal SIG.  */
extern int sigaction (int __sig, const struct sigaction *__restrict __act,
              struct sigaction *__restrict __oact) __THROW;

extern __sighandler_t signal (int __sig, __sighandler_t __handler)
     __THROW;


3、System V

4、消息队列


描       述:产生消息并将其写到队列的进程通常称之为发送者,而一个或多个其他进程(逻辑上称之为接收者)则从队列获取信息。
使用范围:小数据量。

 

// #include <sys/msg.h>
/* Message queue control operation.  */
extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW;

/* Get messages queue.  */
extern int msgget (key_t __key, int __msgflg) __THROW;

/* Receive message from message queue.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t msgrcv (int __msqid, void *__msgp, size_t __msgsz,
               long int __msgtyp, int __msgflg);

/* Send message to message queue.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int msgsnd (int __msqid, const void *__msgp, size_t __msgsz,
           int __msgflg);


5、共享内存


描       述:一个进程向共享内存写入数据,共享这个内存区域的所有进程就可以立即看到其中的内容。
使用范围:大数据通信。使用共享内存需要注意的是多进程之间对一个给定存储区访问的互斥,若一个进程正在向共享区写数据,则在它操作完成之前,其他的进程不应当去读、写这些数据。

// include <sys/shm.h>
/* Shared memory control operation.  */
extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW;

/* Get shared memory segment.  */
extern int shmget (key_t __key, size_t __size, int __shmflg) __THROW;

/* Attach shared memory segment.  */
extern void *shmat (int __shmid, const void *__shmaddr, int __shmflg)
     __THROW;

/* Detach shared memory segment.  */
extern int shmdt (const void *__shmaddr) __THROW;


6、管道和套接字

描       述:管道是用于交换数据的连接。一个进程向管道的一端供给数据,另一个在管道另一端取出数据,供进一步处理。几个进程可以通过一系列管道连接起来。
                  套接字不同于管道,套接字可以双向使用,还可以用于与通过网络连接的远程系统通信。

使用范围:常用于网络、大数据通信。

//#include <unistd.h>
/* Create a one-way communication channel (pipe).
   If successful, two file descriptors are stored in PIPEDES;
   bytes written on PIPEDES[1] can be read from PIPEDES[0].
   Returns 0 if successful, -1 if not.  */
extern int pipe (int __pipedes[2]) __THROW __wur;
/* Close the file descriptor FD.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int close (int __fd);

/* Read NBYTES into BUF from FD.  Return the
   number read, -1 for errors or 0 for EOF.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur;

/* Write N bytes of BUF to FD.  Return the number written, or -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;

//#include <sys/socket.h>
/* Create a new socket of type TYPE in domain DOMAIN, using
   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
   Returns a file descriptor for the new socket, or -1 for errors.  */
extern int socket (int __domain, int __type, int __protocol) __THROW;

/* Put the local address of FD into *ADDR and its length in *LEN.  */
extern int getsockname (int __fd, __SOCKADDR_ARG __addr,
            socklen_t *__restrict __len) __THROW;

/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
   For connectionless socket types, just set the default address to send to
   and the only address from which to accept transmissions.
   Return 0 on success, -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);

/* Send N bytes of BUF to socket FD.  Returns the number sent or -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);

/* Read N bytes into BUF from socket FD.
   Returns the number read or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);

/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
   ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t sendto (int __fd, const void *__buf, size_t __n,
               int __flags, __CONST_SOCKADDR_ARG __addr,
               socklen_t __addr_len);

/* Read N bytes into BUF through socket FD.
   If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of
   the sender, and store the actual size of the address in *ADDR_LEN.
   Returns the number of bytes read or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
             int __flags, __SOCKADDR_ARG __addr,
             socklen_t *__restrict __addr_len);


/* Send a message described MESSAGE on socket FD.
   Returns the number of bytes sent, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t sendmsg (int __fd, const struct msghdr *__message,
            int __flags);
/* Prepare to accept connections on socket FD.
   N connection requests will be queued before further requests are refused.
   Returns 0 on success, -1 for errors.  */
extern int listen (int __fd, int __n) __THROW;

/* Await a connection on socket FD.
   When a connection arrives, open a new socket to communicate with it,
   set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
   peer and *ADDR_LEN to the address's actual length, and return the
   new socket's descriptor, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int accept (int __fd, __SOCKADDR_ARG __addr,
           socklen_t *__restrict __addr_len);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海棠花败

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值