https://github.com/djblue/semaphores
An experiment with semaphores.
https://github.com/djblue/semaphores
Last synced: 15 days ago
JSON representation
An experiment with semaphores.
- Host: GitHub
- URL: https://github.com/djblue/semaphores
- Owner: djblue
- Created: 2015-03-30T08:11:04.000Z (almost 11 years ago)
- Default Branch: master
- Last Pushed: 2015-03-30T17:01:52.000Z (almost 11 years ago)
- Last Synced: 2025-01-19T13:36:44.703Z (12 months ago)
- Language: C
- Size: 238 KB
- Stars: 0
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# tweeter
This project demonstrates thread synchronization using semaphores to
simulate the tweeter social network.
# Building
To build the project, do:
make
To cleanup the project, do:
make clean
# Commands
The following 6 commands are supported:
## Handle
The `Handle` command simply stores a users handle locally to the user
function. This is useful for signing tweets later on.
## Start
The `Start` command will allow a user to start streaming a tweet to the
tweeter thread. Each line is sent separately and the tweet is associated
with the provided `` in the tweeter bank of tweets.
## End
The `End` command will finish a started tweet.
## Follow
The `Follow` command will allow a user to receive all tweets currently
stored in the tweeter bank that have the associated ``.
NOTE: the search on the tweeter bank is a basic linear search that uses
`strcmp` to compare each tweet's tag with the provided search tag.
## Read
The `Read` command will randomly sleep a given user thread.
NOTE: this wont effect the interaction of the stream and tweeter threads
with other users.
## Exit
The `Exit` command will logout a user from their current session.
# Input
Sample input can be found in the `users` directory.
NOTE: all user input is expected to be in the users directory and named
like `user.txt`. If you move one of these files, the program will no
longer work.
# Output
The output is of the following form:
```
[thread identifier]: state/execution information
```
To see an example run, see the `out` directory. The output files are
labeled `.txt`, where `` is the number of users used to generate
that output file. Ex: `./tweeter 2` will be stored in `out/2.txt`.
# Data Structures
The main data structure in the program is the tweet:
```
typedef struct {
char tag[20]; // tag assocaite with tweet
char body[141]; // body of the tweet
int len; // the length of the body
int done; // is the tweet complete or partial
char handle[20]; // handle of users that made the tweet
} tweet;
```
All other variables are either arrays or primitive types.
# Issues
The main issues I ran into with writing the application was running into
deadlocks. In order to deal with these issues, I would trace the output
and see which thread was blocking and how far they made it through their
execution path. Thus, the output was the best source of debugging
deadlocks.
# Pseudo Code
The following pseudo code represents the program:
```
# the in_buff is the buffer for users
# to stream their tweets
tweet in_buff[MAX_USERS]
# mutex to guad in_buff
sem_t in_stream[MAX_USERS] = [1..1]
# semaphores to make sure the tweet has been stored by
# tweeter before continuing, and possibly overwriting
# their previous tweet
sem_t done[MAX_USERS] = [0..0]
# semaphore for tweeter to signal streamer that a
# tweet has been completely processed
sem_t tweet_processed = 0
# mutex to guard the is_ready flag that is set when
# the streamer has recieved a tweet from a user
sem_t ready = 1
# mutexs to guad out_buff
sem_t out_stream[MAX_USERS] = [1..1]
# semaphore for signaling that a user wants to follow
# a tag
sem_t following = 1
# mutex for guarding shared following info such as
# who is following, what tag they are following
sem_t following_info = 1
# semaphore for user to signal the streamer that they
# have finished reading the tweet
sem_t following_read = 0
def tweeter():
while true:
wait(ready)
# process tweet if done, clear tweet
if (is_ready):
# process tweet
signal(tweet_processed)
signal(ready)
wait(following)
if(is_following):
# stream tweet to user
signal(following_processed)
signal(following)
def streamer():
while true:
for i = 0 to n:
wait(in_stream[i])
if in_buff[i].done:
wait(ready)
is_ready = 1
signal(ready)
wait(tweet_processed)
signal(in_stream[i])
def user(id):
for each command in commands:
switch command:
case 'Handle':
# read handle
case 'Start':
for each line in tweet:
wait(in_buff[id])
# stream tweet line to streamer
signal(in_buff[id])
case 'Follow':
wait(following_processed)
wait(following_info)
# set user follow info (user, tag)
signal(following_info)
# recieve tweet stream
while true:
wait(out_stream[id])
if out_buff[id].done:
# access completely streamed tweet
signal(out_stream[id])
# check following flag to see if more tweets
# are coming
wait(following_info)
f = is_following
signal(following_info)
if !f:
break # all tweets have been streamed
case 'Read':
wait(rand())
case 'Exit':
return null
def main(n):
create_thread(tweeter)
create_thread(streamer)
for i = 0 to n:
create_thread(user, i)
```
# Test
To run all the test, do:
make test