信号量用于线程或进程间同步

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <semaphore.h>

#ifndef T_DESC
#define T_DESC(x, y)   (y)
#endif

#if T_DESC("TU1", 1)

sem_t my_sem1;
sem_t my_sem2;

void thread_1(void)
{
    int i;
    for(i=0; i<10; i++)  {
        sem_wait(&my_sem1);
        printf("This is pthread_1.\n");
        sleep(1);
        printf("pthread_1 sleep ok.\n");
        sem_post(&my_sem2);
    }
    pthread_exit(0);
}  

void thread_2(void)
{
    int i;
    for(i=0; i<10; i++) {
        sem_wait(&my_sem2);
        printf("This is pthread_2.\n");
        sleep(2);
        printf("pthread_2 sleep ok.\n");
        sem_post(&my_sem1);
    }
    pthread_exit(0);
}  

int tu1_proc(void)
{
    pthread_t id_1,id_2;
    int i,ret;  

    //int sem_init(sem_t *sem, int pshared, unsigned int value);
    ret = sem_init(&my_sem1, 1, 0);
    if(ret != 0)
    {
        printf("sem_init error!\n");
        return -1;
    } 

    ret = sem_init(&my_sem2, 1, 1); //value为1,避免死锁
    if(ret != 0)
    {
        printf("sem_init error!\n");
        return -1;
    } 

    ret = pthread_create(&id_1, NULL, (void *)thread_1, NULL);
    if(ret != 0)
    {
        printf("Create pthread error!\n");
        return -1;
    }  

    ret = pthread_create(&id_2, NULL, (void *)thread_2, NULL);
    if(ret != 0)
    {
        printf("Create pthread error!\n");
        return -1;
    }  

    /*等待线程结束*/
    pthread_join(id_1, NULL);
    pthread_join(id_2, NULL);  

    sem_destroy(&my_sem1);
    sem_destroy(&my_sem2);

    return 0;
}
#endif

#if T_DESC("TU2", 1)
sem_t *my_shm_sem1;
sem_t *my_shm_sem2;

void thread_21(void)
{
    int i;
    for(i=0; i<10; i++)  {
        sem_wait(my_shm_sem1);
        printf("This is pthread_1.\n");
        sleep(1);
        printf("pthread_1 sleep ok.\n");
        sem_post(my_shm_sem2);
    }
    pthread_exit(0);
}  

void thread_22(void)
{
    int i;
    for(i=0; i<10; i++) {
        sem_wait(my_shm_sem2);
        printf("This is pthread_2.\n");
        sleep(1);
        printf("pthread_2 sleep ok.\n");
        sem_post(my_shm_sem1);
    }
    pthread_exit(0);
}  

int tu2_proc(int argc, char **argv)
{
    pthread_t id_1,id_2;
    int i,ret;
    int param;

    if (argc < 2) return 1;
    param = atoi(argv[1]);

    //sem_t *sem_open(const char *name,int oflag,mode_t mode,unsigned int value);
    my_shm_sem1 = sem_open("my_sem1", O_CREAT, 644, 0);
    if(my_shm_sem1 == 0)
    {
        printf("sem_open error!\n");
        return -1;
    } 

    my_shm_sem2 = sem_open("my_sem2", O_CREAT, 644, 1); //value为1,避免死锁
    if(my_shm_sem2 == 0)
    {
        printf("sem_init error!\n");
        return -1;
    } 

    if (param) {
        ret = pthread_create(&id_1, NULL, (void *)thread_21, NULL);
    } else {
        ret = pthread_create(&id_2, NULL, (void *)thread_22, NULL);
    }
    if(ret != 0)
    {
        printf("Create pthread error!\n");
        return -1;
    }  

    /*等待线程结束*/
    if (param) {
        pthread_join(id_1, NULL);
    } else {
        pthread_join(id_2, NULL);
    }

    sem_close(my_shm_sem1);
    sem_close(my_shm_sem2);

    if (param ) {
        sem_unlink("my_sem1");
        sem_unlink("my_sem2");
    }

    return 0;
}  

#endif

#if T_DESC("global", 1)
void usage()
{
    printf("\n Usage: <cmd> <tu> <p1> <...>");
    printf("\n   1 -- sem between thread");
    printf("\n   2 -- sem between process, need su mode");
    printf("\n     => P1: 0 - create pid 0; 1 - create pid 1");
    printf("\n");
}

int main(int argc, char **argv)
{
    int ret;

    if(argc < 2) {
        usage();
        return 0;
    }

    int tu = atoi(argv[1]);
    if (tu == 1) ret = tu1_proc();
    if (tu == 2) ret = tu2_proc(argc - 1, &argv[1]);

    return ret;
}
#endif

#if T_DESC("readme", 1)
/*
1, how to compile
gcc -o usem.out usem.c -lpthread
gcc -g -o usem.out usem.c -lpthread

*/
#endif
时间: 2024-10-25 08:35:56

信号量用于线程或进程间同步的相关文章

一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与相互排斥一)

各位看官们.大家好,上一回中咱们说的是进程间同步与相互排斥的样例,这一回咱们说的样例是:使用信号量进行进程间同步与相互排斥. 闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,信号量是由著名计算机科学家迪杰斯特拉(Dijkstra)提出的一种概念,专门用来解决进程间同步与相互排斥.在他提出的概念中信号量是一个非负整数值. 信号量的操作仅仅能有两种原子操作: 等待信号; 发送信号. "什么是原子操作呢?"台下有看官在提问.原子操作就是指某个动作在运行时不能被其他动作中断,它会一

进程间同步(1)&mdash;&mdash;条件变量和互斥量

1. 概述 条件变量和互斥量是最基本的同步形式,总是用于同步同一个进程的各个线程间同步. 当把条件变量或互斥量放在共享内存区时,可用于进程间同步. 同样的情况还有读写锁,它们都是随进程的持续性.   2.互斥锁 互斥锁指代相互排斥,用于保护临界区.多个线程和多个进程分享的共享数据. 静态初始化:static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 动态初始化:互斥锁是动态分配的,pthread_mutex_init(&mutex);初始

一个进程间同步和通讯的 C# 框架

转自原文 一个进程间同步和通讯的 C# 框架 threadmsg_demo.zip ~ 41KB    下载 threadmsg_src.zip ~ 65KB    下载 0.背景简介 微软在 .NET 框架中提供了多种实用的线程同步手段,其中包括 monitor 类及 reader-writer锁.但跨进程的同步方法还是非常欠缺.另外,目前也没有方便的线程间及进程间传递消息的方法.例如C/S和SOA,又或者生产者/消费者模式中就常常需要传递消息.为此我编写了一个独立完整的框架,实现了跨线程和跨

RCF—用于C++的进程间通讯(1)

基础 我们从一个标准的echo服务器和客户端的例子来开始,这样的例子可以在几乎所有的网络和IPC示例中见到.我们暴露(expose)然后调用一个函数,这个函数接受一个字符串,并且返回一个相同的字符串,使用RCF,服务器端的代码是这样的:  #include RCFIdl.hpp #include RCFRcfServer.hpp #include RCFTcpEndpoint.hpp RCF_BEGIN(I_Echo, I_Echo)     RCF_METHOD_R1(std::string,

进程间同步---system v ipc 对象信号灯集

一.信号灯简介 Linux支持System V的信号灯(semaphore),是一种进程间通信的方式,只不过它和管道.FIFO或者共享内存不一样,信号灯主要用于同步或者互斥对共享资源的访问,它的发明来源于火车运行系统中的"信号灯",利用信号灯可以实现"PV"操作这种进程间同步进制.P操作时获得资源,将信号灯的值减1,如果结果不为负则执行完毕,进程获得资源,否则进程睡眠以等待的进程释放;V操作则是释放资源,给信号灯的值加1, 唤醒一个因执行P操作而等待的进程. 二.信

linux信号量之进程间同步

概念 linux信号量:允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区. 所在头文件:semaphore.h 主要函数 初始化函数 int sem_init(sem_t *sem, int pshared, unsigned int value) sem:要初始化的信号量 pshared:此信号量是在进程间共享还是线程间共享 value:信号量的初始值 删除函数 int sem_destroy(sem_t *sem) sem:要销

线程(进程)同步--信号量

linux中的信号量既可以用于线程间的同步又可以用于进程间的同步.信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制.在公共资源增加的时候,信号两的值增加:公共资源消耗的时候,信号量的值减少:只有当信号量的值大于大于0的时候,才能访问信号量所带表的公共资源.ps:信号量在linux有posix接口和系统api接口,后者实在是太难记住,所以直接使用前者吧. 有关信号量的主要函数有信号量初始化函数sem_init(3).信号量的销毁函数sem_destroy(1).信号量的增加函数sem_

同步线程和进程间的通信

最近回去学习了一下进程和进程间的通信,有时候很多东西久不看了也就一下子忘了== 这里面有好几个互斥对象使用线程的 1 void mListText(CString str) 2 { 3 m_list_text.AddString(str); 4 m_list_text.SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0); 5 } 6 7 8 9 DWORD WINAPI Thread1(LPVOID lpParameter) 10 { 11 //GetDlgItem(

GIL 线程池 进程池 同步 异步

1.GIL(理论 重点)2.线程池 进程池3.同步 异步 GIL 是一个全局解释器锁,是一个互斥锁 为了防止竞争解释器资源而产生的 为何需要gil:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程 都要执行代码 多线程之间要竞争解释器 一旦竞争就有可能出现问题 带来的问题:同一时间只有一个线程可以访问解释器 好处:保证了多线程的数据安全 thread-safe 线程安全的 多个线程同时访问也不会出问题 not thread-safe 非线程安全的 多个线程同时访问可能