Linux 多线程同步(信号量)

 sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,这信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就 会地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加 一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。

sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同 时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。

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

int myglobal;
sem_t sem;

void * thread_function(void *arg)
{
	int i,j;
	for (i = 0; i < 10; i += 1)
	{
		sem_wait(&sem);
		j = myglobal;
		j = j+1;
		printf(".");
		fflush(stdout);
		sleep(1);
		myglobal = j;
		sem_post(&sem);
	}
	return NULL;
}


int main(void)
{
	pthread_t mythread;
	int i;

	sem_init(&sem, 0, 1);//信号量初始化
	if(pthread_create(&mythread, NULL, thread_function, NULL))
	{
		printf("create thread error!\n");
		abort();
	}

/*	sleep(1);*/

	for(i = 0; i < 10; i++)
	{
		sem_wait(&sem);//=0
		myglobal = myglobal + 1;
		printf("o");
		fflush(stdout);
		sleep(1);
		sem_post(&sem);//=1
	}

	if(pthread_join(mythread, NULL))
	{
		printf("waiting thread failed!\n");
		abort();
	}

	printf("myglobal equals %d\n",myglobal);

	exit(0);
}

例子2:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

void * thread_function(void * arg);
sem_t bin_sem;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];

int main(int argc, char const *argv[])
{
	int res;
	pthread_t pthread;
	void * thread_result;

	res = sem_init(&bin_sem,0,0);//step 1
	if (res != 0)
	{
		perror("sem_init failed!");
		exit(EXIT_FAILURE);
	}

	res = pthread_create(&pthread,NULL,thread_function,NULL);//step 2
	if (res != 0)
	{
		perror("pthread_create failed!");
		exit(EXIT_FAILURE);
	}

	printf("input some text. Enter end to finish\n");
	while(strncmp("end",work_area,3) != 0)
	{	
		fgets(work_area,WORK_SIZE,stdin);
		sem_post(&bin_sem);//step 3
	}
	printf("the final work_area is : %s\n",work_area);//the result is end that reflect every time work_area overload
	res = pthread_join(pthread,&thread_result);
	if (res != 0)
	{
		perror("pthread_join failed!");
		exit(EXIT_FAILURE);
	}

	sem_destroy(&bin_sem);
	exit(EXIT_SUCCESS);
}

void *thread_function(void * arg)
{
	sem_wait(&bin_sem);//if sem value equals 0,and wait,else run 
	while(strncmp("end",work_area,3) != 0)
	{
		printf("you input %d characters\n",strlen(work_area)-1);//remove the enter key
		sem_wait(&bin_sem);//if sem value equals 0,and wait,else run 
	}
	pthread_exit(NULL);
}

保证线程之间的同步!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值