C语言 将基本信号量实现为简单的多线程程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16411355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implementing basic semaphore to simple multi-threads program
提问by leehoyoung
Please help the Synchronization I have to make this program to performe sequentially manner using in threads( ex) thread1 performe and thread2 perforem and so on) But it should be implemented only with Semaphore. I put in the wait(), Signal() function to be act like semaphore(but not working)
请帮助同步我必须使这个程序在线程中以顺序方式执行(例如)thread1 performe 和 thread2 perforem 等等)但它应该只用信号量实现。我放入了 wait(), Signal() 函数作为信号量(但不工作)
You just need to see the pthread_join, and thread_work part (the main purpose of this program : make 20threads and synchorinize them with semaphore)
你只需要看到 pthread_join 和 thread_work 部分(这个程序的主要目的:制作 20 个线程并用信号量同步它们)
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#define num_thread 20
char str[11];
void *thread_work(void *tid); //Main body of Thread working
void generate_str(int n); //Create random character string
void str_sort(void); //Sorting the generated string into alpabet manner
void check_sort(void); //Check about "Is the sorting is right"
void print_time(struct timespec *myclock); //print the time interval of thread work
void print_time_program(struct timespec *myclock);
void wait(void); //I put in these two function to be act like semaphore
void Signal(void); //But it does't work
int S=1;
int main(void)
{
pthread_t tid[num_thread];
int rc;
int t;
struct timespec myclock[4];
srand(time(NULL));
clock_gettime(CLOCK_REALTIME, &myclock[2]);
for(t=0; t<num_thread; t++)
pthread_create(&tid[t], NULL, thread_work, (void *)&t);
for(t=0; t<num_thread; t++)
pthread_join(tid[t], NULL);
clock_gettime(CLOCK_REALTIME, &myclock[3]);
print_time_program(myclock);
return 0;
}
void *thread_work(void *t)
{
do
{
wait(); //Entry Section
//CRITICAL SECTION START
struct timespec myclock[2];
clock_gettime(CLOCK_REALTIME, &myclock[0]);
int n = *((int *)t);
printf("########## Thread #%d starting ########## \n", n);
generate_str(n);
str_sort();
check_sort();
printf("########## Thread #%d exiting ##########\n", n);
clock_gettime(CLOCK_REALTIME, &myclock[1]);
print_time(myclock);
//CRITICAL SECTION END
Signal();
pthread_exit(NULL);
}while (1);
}
void str_sort(void)
{
int temp;
int i, j;
for(i=0; i<9; i++)
for(j=0; j<9-i; j++)
{
if(str[j]>str[j+1])
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
printf("Sorted string : %s ", str);
}
void generate_str(int n)
{
int i;
int num;
srand(n);
for(i=0; i<10; i++)
{
num = (97+rand()%26);
str[i]=num;
}
str[10]='#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_THREADS 5
/* global thread exit control flag */
volatile uint32_t g_ExitFlag = 0;
/* global thread execution control semaphore */
sem_t g_Sem;
/* the thread function */
void *ThreadFunc(void *pContext)
{
uint32_t tid = (uint32_t)pContext;
/* main thread loop */
while (g_ExitFlag == 0)
{
/* wait for semaphore to be signalled */
sem_wait(&g_Sem);
printf("Thread %d running.\n", tid);
}
printf("Thread %d exiting.\n", tid);
return NULL;
}
int main(int argc, char *argv[])
{
uint32_t i = 0;
pthread_t th;
/* suppress warnings */
(void)argc;
(void)argv;
/* initialize the semaphore */
sem_init(&g_Sem, 0, 0);
/* create and detach several threads */
for (i = 0; i < NUM_THREADS; ++i)
{
pthread_create(&th, NULL, ThreadFunc, (void *)i);
pthread_detach(th);
}
/* run each thread four times and exit */
for (i = 0; i < (NUM_THREADS * 4); ++i)
{
if (i == 15)
{
g_ExitFlag = 1;
}
/* release a thread to execute */
sem_post(&g_Sem);
sleep(1);
}
return 0;
}
';
printf("Initialized string : %s \n", str);
}
void check_sort(void)
{
int i;
int count=0;
for(i=0; i<9; i++)
{
if(str[i]>str[i+1])
count++;
}
if(count != 0)
printf("[X] FALSE \n");
else
printf("[O] TRUE \n");
}
void print_time(struct timespec *myclock)
{
long delay, temp, temp_n, sec;
sec = myclock[0].tv_sec % 60;
printf("Thread Starting Time : %ld.%ld second\n", sec, myclock[0].tv_nsec);
sec = myclock[1].tv_sec % 60;
printf("Thread Exiting Time : %ld.%ld second\n", sec, myclock[1].tv_nsec);
if (myclock[1].tv_nsec >= myclock[0].tv_nsec)
{
temp = myclock[1].tv_sec - myclock[0].tv_sec;
temp_n = myclock[1].tv_nsec - myclock[0].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
else
{
temp = myclock[1].tv_sec - myclock[0].tv_sec - 1;
temp_n = 1000000000 + myclock[1].tv_nsec - myclock[0].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
printf("Thread Working Time : %ld nano second", delay);
delay = delay / 1000000;
printf("(%ld ms)\n\n\n", delay);
return ;
}
void print_time_program(struct timespec *myclock)
{
long delay, temp, temp_n, sec;
sec = myclock[2].tv_sec % 60;
printf("Program Starting Time : %ld.%ld second\n", sec, myclock[2].tv_nsec);
sec = myclock[3].tv_sec % 60;
printf("Program Exiting Time : %ld.%ld second\n", sec, myclock[3].tv_nsec);
if (myclock[3].tv_nsec >= myclock[2].tv_nsec)
{
temp = myclock[3].tv_sec - myclock[2].tv_sec;
temp_n = myclock[3].tv_nsec - myclock[2].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
else
{
temp = myclock[3].tv_sec - myclock[2].tv_sec - 1;
temp_n = 1000000000 + myclock[3].tv_nsec - myclock[2].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
printf("Program Total Working Time : %ld nano second", delay);
delay = delay / 1000000;
printf("(%ld ms)\n\n\n", delay);
return ;
}
void wait(void)
{
while( S <= 0);
S--;
}
void Signal(void)
{
S++;
}
回答by Amardeep AC9MF
Here is a working example of how to make threads execute one after another using a semaphore (Linux/Cygwin pthreads):
这是一个如何使用信号量(Linux/Cygwin pthreads)使线程一个接一个执行的工作示例:
##代码##It should be straightforward for you to integrate that kind of functionality into your program.
将这种功能集成到您的程序中应该很简单。

